Farmer John’s cows are showing off their new dance mooves!
At first, all?NN?cows (2≤N≤1052≤N≤105) stand in a line with cow?ii?in the?iith position in line. The sequence of dance mooves is given by?KK?(1≤K≤2?1051≤K≤2?105) pairs of positions?(a1,b1),(a2,b2),…,(aK,bK)(a1,b1),(a2,b2),…,(aK,bK). In each minute?i=1…Ki=1…K?of the dance, the cows in positions?aiai?and?bibi?in line swap. The same?KK?swaps happen again in minutes?K+1…2KK+1…2K, again in minutes?2K+1…3K2K+1…3K, and so on, continuing in a cyclic fashion for a total of?MM?minutes (1≤M≤10181≤M≤1018). In other words,
For each cow, please determine the number of unique positions in the line she will ever occupy.
Note: the time limit per test case on this problem is twice the default.
The first line contains integers?NN,?KK, and?MM. Each of the next?KK?lines contains?(a1,b1)…(aK,bK)(a1,b1)…(aK,bK)?(1≤ai<bi≤N1≤ai<bi≤N).
Print?NN?lines of output, where the?iith line contains the number of unique positions that cow?ii?reaches.
6 4 7 1 2 2 3 3 4 4 5
5 4 3 3 3 1
After?77?minutes, the cows in increasing order of position are?[3,4,5,2,1,6][3,4,5,2,1,6].
Problem credits: Chris Zhang
[/hide]
(Analysis by Chris Zhang)
For the first subtask, we can just simulate. At most?NKNK?minutes will suffice because the sequence of positions of an individual cow will start repeating within that time. For the second subtask, see the silver analysis.
For full credit, let's again construct?sisi?and?pipi?as described in the Silver analysis, and consider the contribution of each disjoint cycle independently.
Let?D=?M/K?D=?M/K??and?RR?be the remainder when?MM?is divided by?KK. There will first occur?DD?full iterations of?KK?swaps, followed by?RR?extra swaps. For simplicity, let’s ignore?RR?for now. To solve for the answer of cow?ii, which is in some cycle of length?LL: if?DD?is at least?LL, the answer is the size of the union of all sets?sisi?in this cycle (as in the silver analysis). But if?DD?is less than?LL, it will be the size of the union of the?DD?sets?si,spi,sp2i,?,spD?1isi,spi,spi2,?,spiD?1. To compute the answers for all cows in a cycle, we maintain a “sliding window” of length?DD?and keep track of the number of unique positions in an array. Specifically, to get the window for?pipi?from the window for?ii, we remove the set?sisi?and add the set?spDispiD.
Now, returning back to?RR. We can actually iterate across each set?sisi?to account for the?RR?extra swaps. This is fast enough because we only iterate across each set at most once, the sum of the sizes of all sets?sisi?is bounded by?2K+N2K+N. To implement this, let the sets?sisi?store pairs which include both the positions and the times at which the positions are reached.
The complexity of this solution is?O(N+K)O(N+K).
Chris’ code:
#include <bits/stdc++.h> using namespace std; typedef long long ll; int N,K; ll M; int A[200001],B[200001]; //input int P[100001]; //as described in analysis int from[100001]; //from[i] = where the cow in position i originated from vector<pair<int,int>>S[100001]; //as described in analysis, stores {pos, time} int cnt[100001]; //array to keep track of uniquePos int uniquePos; //# of unique reachable positions //adds in all reachable positions from S_node where time<=bar void add(int node, int bar){ for (auto x:S[node]){ if (x.second>bar) return; if (cnt[x.first]==0) uniquePos++; cnt[x.first]++; } } //removes all reachable positions from S_node where time<=bar void remove(int node, int bar){ for (auto x:S[node]){ if (x.second>bar) return; if (cnt[x.first]==1) uniquePos--; cnt[x.first]--; } } vector<int>nodes; //stores nodes currently in cycle bool vis[100001]; void dfs(int node){ vis[node]=true; nodes.push_back(node); if (!vis[P[node]]) dfs(P[node]); } int main(){ cin>>N>>K>>M; for (int i=0;i<K;i++) cin>>A[i]>>B[i]; //initialize from and S for (int i=1;i<=N;i++){ from[i]=i; S[i].push_back({i,0}); } //simulate the first K swaps, keeping track of where each position can reach for (int i=0;i<K;i++){ S[from[A[i]]].push_back({B[i],i+1}); S[from[B[i]]].push_back({A[i],i+1}); swap(from[A[i]],from[B[i]]); } //compute array P after first K swaps for (int i=1;i<=N;i++) P[from[i]]=i; int ans[100001]; //run a DFS on each cycle for (int i=1;i<=N;i++) if (!vis[i]){ dfs(i); ll D=M/K; //as described in the analysis int R=M%K; //as described in the analysis //"special case" if the whole cycle is included if (D>=(int)nodes.size()){ D=nodes.size(); R=0; } int j=D-1; //initialize our sliding window [0,j] for (int k=0;k<=j;k++) add(nodes[k],K); //we slide our window [i,j], adding and removing as we go for (int i=0;i<nodes.size();i++){ int newJ=(j+1)%(int)nodes.size(); //account for the extra R swaps add(nodes[newJ],R); //store answer for current sliding window ans[nodes[i]]=uniquePos; //undo the extra R swaps remove(nodes[newJ],R); //undo the left endpoint of sliding window remove(nodes[i],K); //add new right endpoint of sliding window add(nodes[newJ],K); j=newJ; } //reset everything from this cycle for (int k=0;k<=D-1;k++) remove(nodes[k],K);
[/hide]
? 2025. All Rights Reserved. 沪ICP备2023009024号-1