zoukankan      html  css  js  c++  java
  • [AHOI2013]作业 莫队 树状数组

    #include<cmath>
    #include<cstdio>
    #include<algorithm>
    #include<string>
    #include<cstring>
    #include<iostream>
    #define REP(i,a,n)for(int i=a;i<=n;++i)
    #define CLR(d,a)memset(d,a,sizeof(d));
    
    using namespace std;
    
    void SetIO(string a){
        string in=a+".in", out=a+".out";
        freopen(in.c_str(),"r",stdin);
        freopen(out.c_str(),"w",stdout);
    }
    
    void End(){
        fclose(stdin);
        fclose(stdout);
    }
    
    const int maxn=300000+4;
    
    int val[maxn];
    
    int n,m;
    
    struct Queries{
        int l,r,a,b;
        Queries(int l=0,int r=0,int a=0,int b=0):l(l),r(r),a(a),b(b){}
    }ask[maxn];
    
    void Read(){
        scanf("%d%d",&n,&m);
        REP(i,1,n)scanf("%d",&val[i]);
        REP(i,1,m){
            int a,b,c,d;
            scanf("%d%d%d%d",&a,&b,&c,&d);
            ask[i]=Queries(a,b,c,d);
        }
    }
    
    int block, belong[maxn], A[maxn];
    
    int get_belong(int i){ return (i-1)/block+1; }
    
    bool cmp(int i,int j){
        if(belong[ask[i].l]==belong[ask[j].l]) return ask[i].r<ask[j].r;
        return belong[ask[i].l]<belong[ask[j].l];
    }
    
    void Build(){
        block=sqrt(n);
        REP(i,1,n) belong[i]=get_belong(i);
        REP(i,1,m) A[i]=i;
        sort(A+1,A+1+m,cmp);
    }
    
    int count1[maxn];
    
    struct BIT{
        int C[2][maxn];
    
        int lowbit(int t){return t&(-t);}
    
        void update(int pos,int o,int delta){
            while(pos<=n){
                C[o][pos]+=delta;
                pos+=lowbit(pos);
            }
        }
    
        int query(int pos,int o){
            int sum=0;
            while(pos>0){
                sum+=C[o][pos];
                pos-=lowbit(pos);
            }
            return sum;
        }
        void Modify(int i,int delta){
            if(i==0) return ;
            update(i,0,delta);
            count1[i]+=delta;
            if(delta<0 && count1[i]==0) update(i,1,delta);
            if(delta>0 && count1[i]==1) update(i,1,delta); 
        }
    
    }Tree;
    
    int ans1[maxn], ans2[maxn];
    
    void Work(){
        int l=1,r=1;
        Tree.Modify(val[1],1);
        REP(i,1,m){
            int cur=A[i];
            int l2=ask[cur].l;
            int r2=ask[cur].r;
    
      
            if(r<r2) { 
                ++r; 
                while(r<=r2){ Tree.Modify(val[r],1), ++r; }
                --r; 
            } 
            else 
                while(r>r2) { Tree.Modify(val[r],-1), --r; }
    
            if(l<l2) { 
                while(l<l2){ Tree.Modify(val[l],-1);  ++l;  }
            }
            else {
                --l;
                while(l>=l2) { Tree.Modify(val[l],1), --l; }
                ++l;
            }
    
    
            ans1[cur]=Tree.query(ask[cur].b,0)-Tree.query(ask[cur].a-1,0);
            ans2[cur]=Tree.query(ask[cur].b,1)-Tree.query(ask[cur].a-1,1);
        }
    }
    
    void Print(){
        REP(i,1,m)
            printf("%d %d
    ",ans1[i],ans2[i]);
    }
    
    int main(){
        SetIO("input");
        Read();
        Build();
        Work();
        Print();
        End();
        return 0;
    }
  • 相关阅读:
    eslint 的 env 配置是干嘛使的?
    cookie httpOnly 打勾
    如何定制 antd 的样式(theme)
    剑指 Offer 66. 构建乘积数组
    剑指 Offer 65. 不用加减乘除做加法
    剑指 Offer 62. 圆圈中最后剩下的数字
    剑指 Offer 61. 扑克牌中的顺子
    剑指 Offer 59
    剑指 Offer 58
    剑指 Offer 58
  • 原文地址:https://www.cnblogs.com/guangheli/p/9845064.html
Copyright © 2011-2022 走看看