zoukankan      html  css  js  c++  java
  • SP30906

    这是一道带修莫队。

    我们都知道一般的莫队是不带修的,其原理就是把所有的询问先排序然后统一处理。

    但是加入修改之后,可能某些询问中穿插了修改,导致我们无法判断一个区间在被询问之前是否被修改过。

    所以我们可以对于询问和修改操作记录一个时间,并将它的在一个询问操作执行前执行掉它这个时间之前的所有修改操作。

    当然这也只限于单点修改。

    也可以看这里,对于带修莫队有更详细的解释。

    #include<cmath>
    #include<cstdio>
    #include<bitset>
    #include<cstring>
    #include<cstdlib>
    #include<iostream>
    #include<algorithm>
    #define maxn 200100
    #define INF 0x3f3f3f3f
    //#define int long long
    
    using namespace std;
    
    int n,m,len,L=2,R=1,tot,all,cntq,cntc,Now,Ans; 
    int a[maxn],ans[maxn],cnt[maxn],b[maxn];
    struct question{int l,r,t,now;}q[maxn];
    struct change{int pos,val;}c[maxn];
     
    int read(){
        int s=0,w=1;char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-') w=-1;ch=getchar();}
        while(ch>='0'&&ch<='9') s=(s<<1)+(s<<3)+ch-'0',ch=getchar();
        return s*w;
    }
    
    bool cmp(question a,question b){
        return (a.l/len)^(b.l/len)?a.l<b.l:(a.r/len)^(b.r/len)?a.r<b.r:a.t<b.t;
    }
    
    void Add(int x){
        Ans-=(cnt[x]==1);
        Ans+=(++cnt[x]==1);
    }
    
    void Del(int x){
        Ans-=(cnt[x]==1);
        Ans+=(--cnt[x]==1);
    }
    
    void Query(int x,int i){
        if(q[x].l<=c[i].pos&&q[x].r>=c[i].pos){
            Del(a[c[i].pos]),Add(c[i].val);
        }
        swap(a[c[i].pos],c[i].val);
    }
    
    signed main(){
        n=read();m=read();len=pow(n,2.0/3);
        for(int i=1;i<=n;i++) a[i]=read();
        for(int i=1,opt;i<=m;i++){
            opt=read();
            if(opt==1) c[++cntc].pos=read()+1,c[cntc].val=read();
            else q[++cntq].l=read()+1,q[cntq].r=read()+1,q[cntq].now=cntq,q[cntq].t=cntc;
        }
        sort(q+1,q+cntq+1,cmp); 
        for(int i=1;i<=m;i++){
            while(L<q[i].l) Del(a[L++]);
            while(L>q[i].l) Add(a[--L]);
            while(R<q[i].r) Add(a[++R]);
            while(R>q[i].r) Del(a[R--]);
            while(Now<q[i].t) Query(i,++Now);
            while(Now>q[i].t) Query(i,Now--);
            ans[q[i].now]=Ans;
        }
        for(int i=1;i<=cntq;i++) printf("%d
    ",ans[i]);
        return 0;
    }
    
  • 相关阅读:
    开发工程师的职场人生路
    10 ASP.NET Performance and Scalability Secrets(转载推荐)
    手机号码归属地查询接口大全
    参数的秘密“纠结”的压缩比
    爱情本来并不复杂,来来去去不过三个字
    假如苹果、微软、谷歌造汽车 他们的区别是什么
    tomcat修改jsessionid在cookie中的名称
    virtualBox 中 linux 系统 相关配置
    htpasswd用法
    linux 防火墙
  • 原文地址:https://www.cnblogs.com/KnightL/p/14700919.html
Copyright © 2011-2022 走看看