zoukankan      html  css  js  c++  java
  • 2019icpc南昌网络赛_I_Yukino With Subinterval

    题意

    给定一个序列,两种操作,单点修改,询问区间([l,r])值域在([x,y])范围内的连续段个数。

    分析

    • 原数组为(a),构造一个新的数组(b)(b[i]=(a[i]==a[i-1])?0:a[i]),这样将连续段转化为左端点的一个数来表示。
    • 询问就可以转化为维护(b)数组,单点修改和询问区间在某个值域内的数的个数,用树状数组套权值线段树。
    • 类似于差分的思想,对于询问(l,r),我们要查询的是(b)数组的([l+1,r]),因此会漏掉(a[l])这个,所以最后要分情况讨论判断(a[l])是否满足值域条件,若是,无论(a[l+1])是否等于(a[l]),答案都应该再加1。
    • 计蒜客上C++11能34xx(ms)卡过,C++14会T。
    • 树套树学的是这种记录节点,现算现用的方法,貌似用了单独计算累加答案的方法也会T...

    代码

    #include <bits/stdc++.h>
    using namespace std;
    const int N=2e5+150;
    int n,m,a[N],b[N];
    int o,l,r,xi,yi;
    int x[N],y[N];
    int c1,c2;
    int tr[N*150];
    struct HJT{
    #define mid (l+r)/2
        int tot,sum[N*150],ls[N*150],rs[N*150];
        void update(int& rt,int l,int r,int v,int add){
            //因为b数组有0值,在查询时0不算
            if(!v){
                return;
            }
            if(!rt){
                rt=++tot;
            }
            sum[rt]+=add;
            if(l<r){
                if(v<=mid){
                    update(ls[rt],l,mid,v,add);
                }else{
                    update(rs[rt],mid+1,r,v,add);
                }
            }
        }
        //区间[l,r]值域在[1,k]的个数
        int query(int l,int r,int k){
            if(k==0){
                return 0;
            }
            if(r<=k){
                int ans=0;
                for(int i=1;i<=c1;i++){
                    ans-=sum[x[i]];
                }
                for(int i=1;i<=c2;i++){
                    ans+=sum[y[i]];
                }
                return ans;
            }
            if(k<=mid){
                for(int i=1;i<=c1;i++){
                    x[i]=ls[x[i]];
                }
                for(int i=1;i<=c2;i++){
                    y[i]=ls[y[i]];
                }
                return query(l,mid,k);
            }else{
                int ans=0;
                for(int i=1;i<=c1;i++){
                    ans-=sum[ls[x[i]]];
                }
                for(int i=1;i<=c2;i++){
                    ans+=sum[ls[y[i]]];
                }
                for(int i=1;i<=c1;i++){
                    x[i]=rs[x[i]];
                }
                for(int i=1;i<=c2;i++){
                    y[i]=rs[y[i]];
                }
                return ans+query(mid+1,r,k);
            }
        }
    }ac;
    struct BIT{
        int lowbit(int x){
            return x&(-x);
        }
        //修改权值线段树的bit前缀和(非连续)
        void modify(int i,int x){
            int k=b[i];
            while(i<=n){
                ac.update(tr[i],1,n,k,x);
                i+=lowbit(i);
            }
        }
        //预处理权值线段树的查询路径
        int query(int l,int r,int xi,int yi){
            c1=c2=0;
            for(int i=(l-1);i;i-=lowbit(i)){
                x[++c1]=tr[i];
            }
            for(int i=r;i;i-=lowbit(i)){
                y[++c2]=tr[i];
            }
            int R=ac.query(1,n,yi);
            c1=c2=0;
            for(int i=(l-1);i;i-=lowbit(i)){
                x[++c1]=tr[i];
            }
            for(int i=r;i;i-=lowbit(i)){
                y[++c2]=tr[i];
            }
            int L=ac.query(1,n,xi-1);
            return R-L;
        }
    }bit;
    int main(){
    //    freopen("in.txt","r",stdin);
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++){
            scanf("%d",&a[i]);
            b[i]=(a[i]==a[i-1])?0:a[i];
        }
        for(int i=1;i<=n;i++){
            bit.modify(i,1);
        }
        for(int i=1;i<=m;i++){
            scanf("%d%d%d",&o,&l,&r);
            if(o==1){
                bit.modify(l,-1);
                bit.modify(l+1,-1);
                a[l]=r;
                b[l]=(a[l]==a[l-1])?0:a[l];
                b[l+1]=(a[l+1]==a[l])?0:a[l+1];
                bit.modify(l,1);
                bit.modify(l+1,1);
            }else{
                scanf("%d%d",&xi,&yi);
                int ans=bit.query(l+1,r,xi,yi);
                if(a[l]>=xi && a[l]<=yi){
                    ans++;
                }
                printf("%d
    ",ans);
            }
        }
        return 0;
    }
    
  • 相关阅读:
    形式化描述硬件系统
    形式化表述
    采样定理和采样率和采样电路和采样buf_size_frame_size
    Biology 042: Afterimage Effect
    Algo 33: DFS (Depth First Search in Graph)
    174 Python程序中的进程操作进程间通信(multiprocess.Queue)
    018 Django项目SECRET_KEY等敏感信息保存
    017 nodejs取参四种方法req.body,req.params,req.param,req.body
    173 Python程序中的进程操作进程同步(multiprocess.Lock)
    172 Python程序中的进程操作开启多进程(multiprocess.process)
  • 原文地址:https://www.cnblogs.com/zxcoder/p/11496897.html
Copyright © 2011-2022 走看看