洛谷 P4168 蒲公英 分块入门
我学分块入门的第二题,其实它应该作为第一题做的
虽然之前做过一道类似的题目:作诗, 但是还是调试了很长的时间, 很多细节的地方经常搞错
看来代码还是得多练
先记录一下代码:
1 #include<cstdio> 2 #include<algorithm> 3 #include<cmath> 4 #include<cstring> 5 #include<iostream> 6 using namespace std; 7 const int maxn = 40010; 8 const int maxm = 210; 9 10 struct u { 11 int v,i; 12 bool operator < (const u &rhs) const { 13 return v < rhs.v; 14 } 15 }B[maxn]; 16 17 int n, m, N, S, c; 18 int A[maxn], F[maxm][maxm], G[maxm][maxn], ID[maxn], cnt[maxn], cntM[maxn]; 19 int rk[maxn], col[maxn], frk[maxn]; 20 21 bool cmp(u x,u y) { 22 return x.i < y.i; 23 } 24 25 void lsh() { 26 sort(B+1,B+n+1); 27 for(int i = 1;i <= n;i++) { 28 if(B[i].v != col[B[i-1].v]) c++; 29 col[c] = B[i].v; 30 B[i].v = c; 31 } 32 sort(B+1,B+n+1,cmp); 33 for(int i = 1;i <= n;i++) A[i] = B[i].v; 34 } 35 36 int query(int x,int y,int t) { 37 int ret = 0, MX, MX_i; 38 39 if(ID[x] + 1 >= ID[y]) { 40 MX = 0, MX_i = 0; 41 for(int i = x;i <= y;i++) { 42 if(cntM[A[i]] != t) { 43 cntM[A[i]] = t; 44 cnt[A[i]] = 0; 45 } 46 cnt[A[i]]++; 47 int tp = cnt[A[i]]; 48 if(tp > MX || (tp == MX && A[i] < MX_i)) { 49 MX = tp; 50 MX_i = A[i]; 51 } 52 } 53 return col[MX_i]; 54 } 55 56 ret = F[ID[x]+1][ID[y]-1]; 57 MX = G[ID[y]-1][ret] - G[ID[x]][ret], MX_i = ret; 58 for(int i = x;i <= y;) { 59 if(cntM[A[i]] != t) { 60 cntM[A[i]] = t; 61 cnt[A[i]] = 0; 62 } 63 64 cnt[A[i]]++; 65 int tp = cnt[A[i]] + G[ID[y]-1][A[i]] - G[ID[x]][A[i]]; 66 //cout<<ID[y-1]*S+1<<endl; 67 if(tp > MX || (tp == MX && A[i] < MX_i)) { 68 MX = tp; 69 MX_i = A[i]; 70 } 71 72 if(i == ID[x]*S) i = (ID[y]-1)*S+1; 73 else i++; 74 } 75 76 return col[MX_i]; 77 } 78 79 int main() { 80 //freopen("d.txt","r",stdin); 81 scanf("%d %d",&n,&m); 82 S = sqrt(n); 83 N = (n-1)/S + 1; 84 for(int i = 1;i <= n;i++) { 85 scanf("%d",&A[i]); 86 B[i].v = A[i]; 87 B[i].i = i; 88 ID[i] = (i-1)/S + 1; 89 } 90 91 lsh(); 92 93 int Max = 0, Max_i = n+1; 94 for(int i = 1;i <= N;i++) { 95 int t = i; 96 Max = 0; 97 Max_i = 0; 98 for(int j = S*(i-1)+1; j <= n;j++) { 99 int p = ID[j]; 100 if(cntM[A[j]] != t) { 101 cnt[A[j]] = 0; 102 cntM[A[j]] = t; 103 } 104 cnt[A[j]]++; 105 int tp = cnt[A[j]]; 106 if(tp > Max || (tp == Max && Max_i > A[j])) { 107 Max = tp; 108 Max_i = A[j]; 109 } 110 if(j%S == 0) F[i][p] = Max_i; 111 } 112 } 113 114 memset(cnt,0,sizeof(cnt)); 115 for(int i = 1;i <= n;i++) { 116 cnt[A[i]]++; 117 if(i%S == 0 || i == n) { 118 for(int j = 1;j <= c;j++) { 119 G[ID[i]][j] = cnt[j]; 120 } 121 } 122 } 123 124 int ans = 0; 125 for(int i = 1,x,y;i <= m;i++) { 126 scanf("%d %d",&x,&y); 127 x = (x+ans-1)%n + 1; 128 y = (y+ans-1)%n + 1; 129 if(x > y) swap(x,y); 130 // cout <<x<< " : "<<y<<endl; 131 ans = query(x,y,i+n); 132 printf("%d\n", ans); 133 } 134 135 return 0; 136 }