7GOJ 25 collection [分块][莫队]

来源:互联网 发布:java web项目案例 编辑:程序博客网 时间:2024/06/05 03:21

原题就是BZOJ4241
XGG出的原题。。。我用莫队+分块暴力,结果subtaskGG了,改了一下块的大小,O(n)>O(nlogn),就AC了?GG垃圾卡莫队题。

#include<cmath>#include<vector>#include<cstdio>#include<cstring>#include<iostream>#include<algorithm>const int N = 200010;using namespace std;long long n,m,block_size,belong[N],LM[N],RM[N];vector<long long>G[N];long long val[N],ans[N],size[N],num[N],block[N],like[N],temp[N],base[N],tot[N],sum[N];struct query{    long long l,r,id;}q[N];inline void read(long long &res){    static char ch;long long flag=1;    while((ch=getchar())<'0'||ch>'9')if(ch=='-')flag=-1;res=ch-48;    while((ch=getchar())>='0'&&ch<='9')res=res*10+ch-48;res*=flag;}inline bool cmp(const query &a,const query &b){    if(belong[a.l]==belong[b.l]){        if(belong[a.l]%2==1)return a.r<b.r;        else return a.r>b.r;    }else return belong[a.l]<belong[b.l];}int main(){    read(n),read(m);    block_size=sqrt(n*(double)log(n*1.0)/log(2.0));//无解了,就一个块大小就能卡死我?    for(register long long x,i=1;i<=n;++i)        read(x),like[i]=temp[i]=x,belong[i]=(i-1)/block_size;    sort(temp+1,temp+n+1);    for(register long long i=1;i<=n;++i)        base[i]=lower_bound(temp+1,temp+n+1,like[i])-temp,val[i]=like[i]*++size[base[i]];    sort(val+1,val+n+1);    for(register long long i=1;i<=n;++i)        G[base[i]].push_back(lower_bound(val+1,val+n+1,like[i]*++num[base[i]])-val);    for(register long long i=1;i<=m;++i)read(q[i].l),read(q[i].r),q[i].id=i;    sort(q+1,q+m+1,cmp);    for(register long long i=1;i<=n;++i)        belong[i]=(i-1)/block_size+1;    for(register long long i=1;i<=belong[n];++i)        LM[i]=(i-1)*block_size+1,RM[i]=min(n,i*block_size);    for(register long long i=1,L=1,R=0;i<=m;++i){        while(R<q[i].r){            R++;            sum[belong[G[base[R]][block[base[R]]]]]++;            tot[G[base[R]][block[base[R]]]]++;            block[base[R]]++;        }        while(L>q[i].l){            L--;            sum[belong[G[base[L]][block[base[L]]]]]++;            tot[G[base[L]][block[base[L]]]]++;            block[base[L]]++;        }        while(L<q[i].l){            block[base[L]]--;            sum[belong[G[base[L]][block[base[L]]]]]--;            tot[G[base[L]][block[base[L]]]]--;            L++;        }        while(R>q[i].r){            block[base[R]]--;            sum[belong[G[base[R]][block[base[R]]]]]--;            tot[G[base[R]][block[base[R]]]]--;            R--;        }        for(register long long j=belong[n];j>=0;j--)            if(sum[j])for(register long long k=RM[j];k>=LM[j];k--)                if(tot[k]){                    ans[q[i].id]=val[k];goto LMY;                }        LMY:;    }    for(register long long i=1;i<=m;++i)cout<<ans[i]<<endl;    return 0;}

安利一下neither_nor大佬的回滚莫队%%%
那么回滚莫队是什么?不知道。。