洛谷 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 } 

 

posted @ 2018-08-21 16:03  Frank的成长之路  阅读(231)  评论(0编辑  收藏  举报