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