zoukankan      html  css  js  c++  java
  • 回滚莫队 刷题记录

    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
    ", pa[i]);
    88     return 0;
    89 }
    ( *^-^)ρ(*╯^╰)
  • 相关阅读:
    Android开发学习——应用安装过程
    飞信接口
    sql联合查询
    宽度自适应
    数据绑定
    分页查询sql
    asp.net读取文件
    oracle数据库连接
    oracle服务的开始和关闭 CMD
    css导航条
  • 原文地址:https://www.cnblogs.com/jiecaoer/p/11980402.html
Copyright © 2011-2022 走看看