[SDOI2008]郁闷的小J(带修莫队)

[SDOI2008]郁闷的小J(luogu)

Solution

带修莫队模板?

先将所有读入中有的编码离散

每经过一次修改操作,将时间加一

对于每次查询,记录A,B,时间

将时间作为第三个排序元素,跑莫队

Code

#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <algorithm>
using namespace std;
const int N=1e5+10;
struct node
{
    int x,id;
    bool operator <(const node &o)const
    {
        return x<o.x;
    }
}a[N*4];
int n,m,d[N],s[N*4],T[N][3],tot,cnt,sc,sq,x,y,k,si,nl,nr,nt,ans[N];
char ss[5];
struct mode
{
    int l,r,t,id,k;
    bool operator <(const mode &o)const
    {
        return l/si==o.l/si?(r/si==o.r/si?t<o.t:r<o.r):l<o.l;
    }
}q[N];
int read()
{
    int sum=0,fh=1;
    char ch=getchar();
    while(!(ch>='0' && ch<='9'))
    {
        if(ch=='-') fh=-1;
        ch=getchar();
    }
    while(ch>='0' && ch<='9' && ch!=EOF) sum=sum*10+ch-48,ch=getchar();
    return sum*fh;
}
int main()
{
    n=read(),m=read();
    int once=n+m;
    for(int i=1;i<=n;i++)
    {
        d[i]=read();
        a[++tot]=(node){d[i],i+once*3};
    }
    for(int i=1;i<=m;i++)
    {
        scanf("%s",ss);
        scanf("%d%d",&x,&y);
        if(ss[0]=='C')
        {
            if(d[x]==y) continue;
            T[++sc][0]=x,T[sc][1]=d[x],T[sc][2]=y;
            a[++tot]=(node){d[x],sc+once},a[++tot]=(node){y,sc+once*2};
            d[x]=y;
        }
        else if(ss[0]=='Q')
        {
            scanf("%d",&k);
            q[++sq]=(mode){x,y,sc,sq,k};
            a[++tot]=(node){k,sq};
        }
    }
    sort(a+1,a+1+tot);
    for(int i=1;i<=tot;i++)
    {
        if(i==1 || a[i].x!=a[i-1].x) cnt++;
        x=a[i].id%once,y=a[i].id/once;
        if(y==0) q[x].k=cnt;
        else if(y<3) T[x][y]=cnt;
        else d[x]=cnt;
    }
    si=pow(n,0.6666667);
    sort(q+1,q+1+sq);
    for(int i=1;i<=sq;i++)
    {
        int l=q[i].l,r=q[i].r,t=q[i].t;
        while(nl<l) s[d[nl++]]--;
        while(nl>l) s[d[--nl]]++;
        while(nr<r) s[d[++nr]]++;
        while(nr>r) s[d[nr--]]--;
        while(nt<t)
        {
            nt++;
            if(nl<=T[nt][0] && nr>=T[nt][0]) s[T[nt][1]]--,s[T[nt][2]]++;
            d[T[nt][0]]=T[nt][2];
        }
        while(nt>t)
        {
            if(nl<=T[nt][0] && nr>=T[nt][0]) s[T[nt][1]]++,s[T[nt][2]]--;
            d[T[nt][0]]=T[nt][1];
            nt--;
        }
        ans[q[i].id]=s[q[i].k];
    }
    for(int i=1;i<=sq;i++) printf("%d\n",ans[i]);
    return 0;
}

 

猜你喜欢

转载自www.cnblogs.com/hsez-cyx/p/12446620.html