【模板】【回滚莫队】洛谷p5906

回滚莫队就是在莫队的基础上加上回滚操作,右端点单调往右移动,左端点每次从块的最右端(br)移到询问的r , 再直接移动回来br,保存 [ br , r ] 的信息,移动到 [ l , r ] 后 直接回滚到 [br , r ] 继续进行上述操作

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 const int N = 2e5+9;
 4 struct Que{
 5     int l,r,lid;
 6     int id,ans;
 7 }q[N];
 8 int num[N],mx[N],mi[N],las_mx[N],las_mi[N],blo[N];
 9 int calmi[N];
10 int a[N];
11 int n,m;
12 bool cmp(Que a,Que b){
13     if(a.lid == b.lid ) return a.r < b.r;
14     return a.lid < b.lid;
15 }
16 bool cmpid(Que a,Que b){
17     return a.id < b.id;
18 }
19 int cal(int le,int ri){
20     int res = 0;
21     for(int i = le;i<=ri;++i){
22         if(!calmi[a[i]]) calmi[a[i]] = i;
23         else res = max(res,i - calmi[a[i]]);
24     }
25     for(int i = le;i<=ri;++i) calmi[a[i]] = 0;
26     return res;
27 }
28 void Mo(){
29     sort(q+1,q+1+m,cmp);
30     int len = sqrt(n);
31     int qid = 1,bid = q[1].lid;
32     for(;bid<=blo[n];++bid){
33         int br = min( n,bid * len);
34         int le = br+1,ri = le-1;
35         int cur_ans = 0,las_ans = 0;
36         vector<int> r_use;
37         for(;q[qid].lid == bid;++qid){
38 
39             if( blo[ q[qid].r ] == bid){
40                 q[qid].ans = cal(q[qid].l,q[qid].r);
41                 continue;
42             }
43 
44             while(ri < q[qid].r ){
45                 ++ri;
46                 r_use.push_back(a[ri]);
47                 mx[ a[ri] ] = ri;
48                 if(!mi[a[ri]]) mi[a[ri]] = ri;
49                 cur_ans = max(cur_ans,ri - mi[a[ri]]);
50                 las_mx[a[ri]] = mx[a[ri]];
51                 las_mi[a[ri]] = mi[a[ri]];
52             }
53             las_ans = cur_ans;
54             vector<int> l_use;
55             while(le > q[qid].l){
56                 --le;
57                 l_use.push_back(a[le]);
58                 if(mx[a[le]]) cur_ans = max(cur_ans,mx[a[le]] - le);
59                 else mx[a[le]] = le;
60             }
61             q[qid].ans = cur_ans;
62             cur_ans = las_ans;
63             for(auto it : l_use){
64                 mx[it] = las_mx[it];
65                 mi[it] = las_mi[it];
66             }
67             le = br+1;
68         }
69         for(auto it : r_use) mx[it] = mi[it] = las_mx[it] = las_mi[it] = 0;
70     }
71 }
72 void init(){ 
73     scanf("%d",&m);
74     int len = sqrt(n);
75     for(int i= 1;i<=n;++i) blo[i] = (i-1)/len + 1;
76     for(int i = 1;i<=m;++i){
77         q[i].id = i;
78         scanf("%d %d",&q[i].l,&q[i].r);
79         q[i].lid = blo[ q[i].l ] ;
80     }
81 }
82 int main(){
83     scanf("%d",&n);
84     int cnt = 0;
85     for(int i = 1;i<=n;++i){
86         scanf("%d",a+i);
87         num[++cnt] = a[i];
88     }
89     sort(num+1,num+1+cnt);
90     cnt = unique(num+1,num+1+cnt) - num - 1;
91     for(int i = 1;i<=n;++i) a[i] = lower_bound(num+1,num+1+cnt,a[i]) - num;
92     init();
93     Mo();
94     sort(q+1,q+1+m,cmpid);
95     for(int i = 1;i<=m;++i) printf("%d\n",q[i].ans);
96     return 0;
97 }
View Code

 

posted @ 2020-03-27 16:39  小布鞋  阅读(187)  评论(0编辑  收藏  举报