zoukankan      html  css  js  c++  java
  • P4396 [AHOI2013]作业

    思路

    因为每次a和b不相同
    用莫队+分块或者莫队+树状数组即可维护
    不过分块单点修改是O(1)的,更优
    我用树状数组维护了一下,只能开O2通过

    代码

    #include <cstdio>
    #include <algorithm>
    #include <cstring>
    #include <cmath>
    using namespace std;
    struct BIT{
        int tr[10000000],MAXW;
        int lowbit(int x){
            return x&(-x);
        }
        void add(int pos,int c){
            pos++;
            while(pos<=MAXW){
                tr[pos]+=c;
                pos+=lowbit(pos);
            }
        }
        int query(int pos){
            pos++;
            int ans=0;
            while(pos){
                ans+=tr[pos];
                pos-=lowbit(pos);
            }
            return ans;
        }
    }times,nums;
    int color[10000000],a[100100],n,m,L,R,sz,num,belong[100100],ans1[100100],ans2[100100];
    struct Query{
        int l,r,a,b,id;
        bool operator < (const Query &b) const{
            return (belong[l]==belong[b.l])?r<b.r:belong[l]<belong[b.l];
        }
    }Q[100100];
    void init(void){
        sz=sqrt(n);
        num=n/sz;
        if(n%sz)
            num++;
        for(int i=1;i<=n;i++)
            belong[i]=i/sz+1;
    }
    void moveL(int opt){
        if(opt==1){
            times.add(a[L],-1);
            if(color[a[L]]==1)
                nums.add(a[L],-1);
            color[a[L]]--;
            L++;
        }
        else{
            L--;
            times.add(a[L],1);
            if(color[a[L]]==0)
                nums.add(a[L],1);
            color[a[L]]++;
        }
    }
    void moveR(int opt){
        if(opt==1){
            R++;
            times.add(a[R],1);
            if(color[a[R]]==0)
                nums.add(a[R],1);
            color[a[R]]++;    
        }
        else{
            times.add(a[R],-1);
            if(color[a[R]]==1)
                nums.add(a[R],-1);
            color[a[R]]--;
            R--;
        }
    }
    int main(){
        scanf("%d %d",&n,&m);
        init();
        for(int i=1;i<=n;i++){
            scanf("%d",&a[i]);
            times.MAXW=nums.MAXW=max(nums.MAXW,a[i]+10);
        }
        for(int i=1;i<=m;i++)
            scanf("%d %d %d %d",&Q[i].l,&Q[i].r,&Q[i].a,&Q[i].b),Q[i].id=i;
        sort(Q+1,Q+m+1);
        L=R=0;
        for(int i=1;i<=m;i++){
            while(L<Q[i].l)
                moveL(1);
            while(L>Q[i].l)
                moveL(-1);
            while(R<Q[i].r)
                moveR(1);
            while(R>Q[i].r)
                moveR(-1);
            ans1[Q[i].id]=times.query(Q[i].b)-times.query(Q[i].a-1);
            ans2[Q[i].id]=nums.query(Q[i].b)-nums.query(Q[i].a-1);
        }
        for(int i=1;i<=m;i++)
            printf("%d %d
    ",ans1[i],ans2[i]);
        return 0;
    }
    
    
  • 相关阅读:
    C#调用Delphi的dll 详解
    C# 用API截取桌面屏幕
    C# 控件代码设置置顶和置底属性
    C#用API 获取电脑桌面背景图地址
    利用JS使IE浏览器默认打开是全屏显示
    aspx页面生成xml数据
    MacOS下安装Anaconda+Pycharm+TensorFlow+Keras
    GitHub编辑README
    Win10(64位)下安装Anaconda+Tensorflow(GPU)
    Win7(64位)下安装Anaconda+Tensorflow(CPU)
  • 原文地址:https://www.cnblogs.com/dreagonm/p/10805546.html
Copyright © 2011-2022 走看看