# 洛谷 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的成长之路  阅读(232)  评论(0编辑  收藏  举报