ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

回滚莫队 刷题记录

2019-12-03 23:52:51  阅读:264  来源: 互联网

标签:回滚 f1n int lsh qe 刷题 莫队 ta


BZOJ4241: 历史研究

给一个长为n的数组,q次查询,查询l~r区间内某个数的值乘以该数出现的次数的最大值。

明显添加比较容易删除比较难,所以回滚莫队

先离散化数,然后在莫队的时候维护桶。

所谓回滚莫队就是lefl每次都到块的最右边这样就不会有删除操作了。

 1 #include <bits/stdc++.h>
 2 #define nmax 100010
 3 #define f1n for(int i=1; i<=n; i++)
 4 
 5 using namespace std;
 6 typedef long long ll;
 7 int n, q, nb, cb;
 8 ll pa[nmax], cnt[nmax], fi[nmax];
 9 int c[nmax];
10 int pos[nmax];
11 struct ques{
12     int l, r, pl, id;
13     bool operator < (const ques myc) const {
14         return (myc.pl==pl) ? (myc.r>r) : (myc.pl>pl) ;
15     } //----------
16 }qe[nmax];
17 struct mylsh{
18     ll x; 
19     int id;
20     bool operator < (const mylsh myc) const { return myc.x > x; }
21 }lsh[nmax];
22 
23 void build(){
24     scanf("%d%d", &n, &q);
25     nb = (int)sqrt(n);
26     f1n {
27         scanf("%lld", &lsh[i].x);
28         lsh[i].id = i;
29     }
30     sort(lsh+1, lsh+1+n);
31     int j=0;  
32     lsh[0].x = lsh[1].x+1; 
33     f1n{
34         if(lsh[i].x != lsh[i-1].x) j++;
35         c[ lsh[i].id ] = j;
36         fi[j] = lsh[i].x;
37     }
38     f1n pos[i] = (i-1)/nb+1; //--------
39     for (int i=1; i<=q; i++) {
40         scanf("%d%d", &qe[i].l, &qe[i].r);
41         qe[i].id = i;
42         qe[i].pl = pos[ qe[i].l ];
43     }
44     sort(qe+1, qe+1+q);
45 }
46 
47 inline void upd(int p, ll& ta){
48     cnt[ c[p] ]++;
49     ta = max( ta, cnt[ c[p] ]*fi[ c[p] ] );
50 }
51 
52 inline void init(){  memset(cnt,0,sizeof(cnt)); }
53 
54 inline ll myf(int l, int r){
55     ll ans=0;
56     for (int i=l; i<=r; i++) {
57         cnt[ c[i] ]++;
58         ans = max(ans, cnt[ c[i] ] * fi[ c[i] ] );
59     }
60     for (int i=l; i<=r; i++) cnt[ c[i] ]--;
61     return ans;
62 }
63 
64 int main(){
65     //freopen("owo.in","r",stdin);
66     build();
67     int tr, tmp;
68     ll ta;
69     qe[0].pl=-1;
70     for (int i=1; i<=q; i++) {
71         if( qe[i].pl != qe[i-1].pl ) {
72             init();
73             tmp = qe[i].pl*nb;
74             tr = tmp;
75             ta = 0;
76         }
77         if( pos[ qe[i].r ] == qe[i].pl ) pa[ qe[i].id ] = myf(qe[i].l, qe[i].r);
78         else{
79             while(qe[i].r>tr) { tr++; upd(tr, ta); }
80             ll jl = ta;
81             for (int k = tmp; k>=qe[i].l; k--) upd(k, ta); 
82             pa[ qe[i].id ] = ta;
83             for (int k = tmp; k>=qe[i].l; k--) cnt[ c[k] ]--; //撤销影响
84             ta = jl;
85         }
86     }
87     for (int i=1; i<=q; i++) printf("%lld\n", pa[i]);
88     return 0;
89 }
( *^-^)ρ(*╯^╰)

 

标签:回滚,f1n,int,lsh,qe,刷题,莫队,ta
来源: https://www.cnblogs.com/jiecaoer/p/11980402.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有