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;
    }
  • 相关阅读:
    Java的Object类
    java中String、StringBuffer、StringBuilder的区别
    Java正则表达式
    《java编程思想》P160-P180(第八章部分+第九章部分)
    《java编程思想》P140-P160(第七章复部+第八章部分)
    《java编程思想》P125-P140(第七章复用类部分)
    Servlet 工作原理解析
    大型高性能网站的十项规则
    Java 理论与实践: 并发在一定程度上使一切变得简单
    Java并发基础构建模块简介
  • 原文地址:https://www.cnblogs.com/guangheli/p/9845064.html
Copyright © 2011-2022 走看看