• BZOJ3236作业


    这东西是个应用为O(logn)的莫队。

    正常莫队的updata函数转移是O(1)的,可这个题时间非常宽泛,可以套两个树状数组,那两个东西很好维护,第一个直接普通权值树状数组维护,第二个开一个桶,记录当前区间内某个数的出现次数,当从0->1时,第二个树状数组+权,1->0时,第二个树状数组-权,别的情况不用管,这样就可以用莫队轻松搞掉了。

    #include<bits/stdc++.h>
    #define lowbit(x) (x&(-x))
    using namespace std;
    int read(){
        int sum=0,f=1;char x=getchar();
        while(x<'0'||x>'9'){
            if(x=='-') f=-1;
            x=getchar();
        }while(x>='0'&&x<='9'){
            sum=sum*10+x-'0';
            x=getchar();
        }return sum*f;
    }
    struct MoCap{
        int l,r,id,a,b;
    }q[1000500];
    int n,m,part,L,R,ans1[1000500],ans2[1000500];
    int bl[100500],col[100500],t1[100500],t2[100500],cnt[100500];
    bool cmp(MoCap a,MoCap b){
        return bl[a.l]==bl[b.l]?a.r<b.r:a.l<b.l;
    }
    void add1(int pos,int val){
        for(int i=pos;i<=n;i+=lowbit(i))
            t1[i]+=val;
    }
    int ask1(int pos){
        int ans=0;
        for(int i=pos;i>=1;i-=lowbit(i))
            ans+=t1[i];
        return ans;
    }
    void add2(int pos,int val){
        for(int i=pos;i<=n;i+=lowbit(i))
            t2[i]+=val;
    }
    int ask2(int pos){
        int ans=0;
        for(int i=pos;i>=1;i-=lowbit(i))
            ans+=t2[i];
        return ans;
    }
    void updata(int i,int val){
        if(cnt[col[i]]==1&&val==-1){
            add2(col[i],val);
        }
        if(cnt[col[i]]==0&&val==1){
            add2(col[i],val);
        }
        add1(col[i],val);
        cnt[col[i]]+=val;
    //    qaq1=ask1(R)-ask1(L-1);
    //    qaq2=ask2(R)-ask2(L-1);
    }
    int main(){
        n=read();m=read();part=sqrt(n);
        for(int i=1;i<=n;i++){
            col[i]=read();
            bl[i]=i/part+1;
        }
        for(int i=1;i<=m;i++){
            q[i].l=read();
            q[i].r=read();
            q[i].a=read();
            q[i].b=read();
            q[i].id=i;
        }sort(q+1,q+1+m,cmp);
        int l=1,r=0;
        for(int i=1;i<=m;i++){
            L=q[i].a;R=q[i].b;
            while(l<q[i].l) updata(l++,-1);
            while(l>q[i].l) updata(--l,+1);
            while(r<q[i].r) updata(++r,+1);
            while(r>q[i].r) updata(r--,-1);
            ans1[q[i].id]=ask1(R)-ask1(L-1);
            ans2[q[i].id]=ask2(R)-ask2(L-1);
        }
        for(int i=1;i<=m;i++)
            printf("%d %d
    ",ans1[i],ans2[i]);
        return 0;
    }
    View Code
  • 相关阅读:
    架构设计
    git 常用命令
    C# 加载C++的dll
    windows 服务部署管理
    wpf 模板绑定控件属性
    golang开启module模式 go mod
    使用docker安装redis
    使用docker安装elasticsearch
    使用docker安装etcd
    使用docker安装mysql5.7
  • 原文地址:https://www.cnblogs.com/Yu-shi/p/11240941.html
Copyright © 2020-2023  润新知