卡常の神题
查看原帖
卡常の神题
684245
zhangyaiwei楼主2024/11/12 14:18

RT,已经交了两面了,第十个点死活卡不过去

写的可持久化线段树(常数++)

谁来救救我

#include<bits/stdc++.h>
using namespace std;
struct Cjs{
    int v;
    int Lf,Rt;
}ts[23000005];
int n,q,L,R,a[1000005],Top,Root[1000005],lst[1000005],pre[1000005];
inline void PushUp(int w){
    ts[w].v=ts[ts[w].Lf].v+ts[ts[w].Rt].v;
}
int Initt(int l,int r){
    int w=++Top;
    if(l==r){
        return w;
    }
    ts[w].Lf=Initt(l,(l+r)>>1);
    ts[w].Rt=Initt(((l+r)>>1)+1,r);
    return w;
}
int New(int x,int w2,int L,int R){
    int w=++Top;
    ts[w]=ts[w2];
    if(L==R){
        ts[w].v++;
        return w;
    }
    if(x<=(L+R)>>1){
        ts[w].Lf=New(x,ts[w2].Lf,L,(L+R)>>1);
    }
    else{
        ts[w].Rt=New(x,ts[w2].Rt,((L+R)>>1)+1,R);
    }
    PushUp(w);
    return w;
}
int Get(int l,int r,int w,int L,int R){
    if(l<=L&&R<=r){
        return ts[w].v;
    }
    else if(l<=R&&L<=r){
        return Get(l,r,ts[w].Lf,L,(L+R)>>1)+Get(l,r,ts[w].Rt,((L+R)>>1)+1,R);
    }
    return 0;
}
inline int read()
{
    int x=0,f=1;
    char ch=getchar();
    while(ch<'0'||ch>'9')
    {
        if(ch=='-')
            f=-1;
        ch=getchar();
    }
    while(ch>='0' && ch<='9')
        x=x*10+ch-'0',ch=getchar();
    return x*f;
}
void write(int x)
{
    if(x<0)
        putchar('-'),x=-x;
    if(x>9)
        write(x/10);
    putchar(x%10+'0');
    return;
}
int main(){
    ios::sync_with_stdio(false);
    cin.tie(0),cout.tie(0);
    n=read();
    for(int i=1;i<=n;i++){
        a[i]=read();
        pre[i]=lst[a[i]];
        lst[a[i]]=i;
    }
    Root[0]=Initt(1,n);
    for(int i=1;i<=n;i++){
        Root[i]=New(pre[i]+1,Root[i-1],1,n);
    }
    q=read();
    while(q--){
        L=read();
        R=read();
        write(Get(1,L,Root[R],1,n)-Get(1,L,Root[L-1],1,n));
        puts("");
    }
}
2024/11/12 14:18
加载中...