1. 程式人生 > 其它 >區間查不重複元素的個數

區間查不重複元素的個數

原題在此

某位大佬用線段樹做的
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
const int N=3e5+7;
inline int read(){
    int sum=0,f=1;char c=getchar();
    while(!isdigit(c)){if(c=='-') f=-1;c=getchar();}
    while(isdigit(c)){sum=sum*10+c-'0';c=getchar();}
    
return sum*f; } int n,m,s[2*N],lt[N]; int minx[N],maxn[N]; struct Tree{ int l,r; int sum; Tree(){sum=0;} }t[7*N]; inline void build(int p,int l,int r){ t[p].l=l,t[p].r=r; if(l==r) return; int mid=(l+r)>>1; build(p*2,l,mid); build(p*2+1,mid+1,r); } inline int q_sum(int p,int
ql,int qr){ int l=t[p].l,r=t[p].r; if(l==r) return t[p].sum; if(ql<=l&&qr>=r) return t[p].sum; int mid=(l+r)>>1; if(ql<=mid&&qr>mid) return q_sum(p*2,ql,mid)+q_sum(p*2+1,mid+1,qr); if(qr<=mid) return q_sum(p*2,ql,qr); if(ql>mid) return q_sum(p*2
+1,ql,qr); return 0; } inline void revise(int p,int x,int w){//將x位改為w int l=t[p].l,r=t[p].r; if(l==r){ t[p].sum=w; return; } int mid=(l+r)>>1; if(l<=x&&x<=mid) revise(p*2,x,w); else revise(p*2+1,x,w); t[p].sum=t[p*2].sum+t[p*2+1].sum; } int main(){ n=read(),m=read(); build(1,1,n+m); for(int i=n;i>=1;i--){ s[n-i+1]=i,lt[i]=n-i+1; revise(1,n-i+1,1); minx[i]=i; } for(int i=n+1;i<=n+m;i++){ s[i]=read(); minx[s[i]]=1; maxn[s[i]]=max(maxn[s[i]],q_sum(1,lt[s[i]],i)); revise(1,lt[s[i]],0); revise(1,i,1); lt[s[i]]=i; } for(int i=1;i<=n;i++) maxn[i]=max(maxn[i],q_sum(1,lt[i],n+m)); for(int i=1;i<=n;i++) printf("%d %d\n",minx[i],maxn[i]); }
俺用莫隊做的
#include<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<set>
using namespace std;
int N,CC[300005],rank[300005],tree[3000005],front[300005],Q,Size,ans,cs[300005],vis4[300005],p1[300005],n,m,vis1[300005],vis[300005][2],a[300005],p[300005];
int Max(int XXX,int YYY){
    if(XXX<YYY) return YYY;
    return XXX;
}struct Node{
    int id,val;
}cx1[300005];
int Cmp(Node q,Node w){
    if(q.val==w.val) return q.id<w.id;
    return q.val<w.val;
}

struct node{
    int l,r,num;
}cx[300005];

int cmp(node XXX,node YYY){
    if(XXX.l/Size==YYY.l/Size) return XXX.r<YYY.r;
    return XXX.l/Size<YYY.l/Size;
}
int del(int X){
    cs[a[X]]--;
    if(cs[a[X]]==0) ans--;
    return 0;
}
int add(int X){
    if(cs[a[X]]==0) ans++;
    cs[a[X]]++;
    return 0;
}
void insert(int po,int d){
    for(;po<=N;po+=po&-po) tree[po]+=d; 
}
int query(int po){
    int sum=0;
    for(;po;po-=po&-po) sum+=tree[po];
    return sum;
}
int main(){
    scanf("%d%d",&n,&m);
    for(int i=1;i<=m;i++){
        scanf("%d",&a[i]);
        vis1[a[i]]++;
        vis[a[i]][0]=1;
        p[a[i]]=1;
    }
    for(int i=1;i<=n;i++) p[i]+=p[i-1];
    for(int i=1;i<=m;i++){
        if(vis1[a[i]]==1){
            if(i!=m){
                cx[++Q].l=i+1;
                cx[Q].r=m;
                cx[Q].num=a[i];
            }
            cx1[++N].val=a[i];
            cx1[N].id=N;
            CC[N]=a[i];
        }
        else{
            if(vis4[a[i]]==0){
                cx1[++N].val=a[i];
                cx1[N].id=N;
                CC[N]=a[i];
                front[a[i]]=i+1;
                vis4[a[i]]++;
            }
            else{
                vis4[a[i]]++;
                if(vis4[a[i]]==vis1[a[i]]){
                    if(front[a[i]]!=i){
                        cx[++Q].l=front[a[i]];
                        cx[Q].r=i-1;
                        cx[Q].num=a[i];
                    }
                    front[a[i]]=i+1;
                    if(front[a[i]]!=m+1){
                        cx[++Q].l=front[a[i]];
                        cx[Q].r=m;
                        cx[Q].num=a[i];
                    }
                    
                }
                else{
                    if(front[a[i]]!=i){
                        cx[++Q].l=front[a[i]];
                        cx[Q].r=i-1;
                        cx[Q].num=a[i];
                        front[a[i]]=i+1;
                    }
                }
            }
        }
    }
    sort(cx1+1,cx1+1+N,Cmp);
    for(int i=1;i<=N;i++) rank[cx1[i].id]=i;
    for(int i=1;i<=N;i++){
        insert(rank[i],1);
        vis[CC[i]][1]=CC[i]+i-query(rank[i]);
    }
    
    Size=(int)sqrt(m);
    sort(cx+1,cx+Q+1,cmp);
    int l=1,r=0;
    for(int i=1;i<=Q;i++){
        int L=cx[i].l,R=cx[i].r;
        while(l<L) del(l++);
        while(l>L) add(--l);
        while(r<R) add(++r);
        while(r>R) del(r--);
        vis[cx[i].num][1]=Max(vis[cx[i].num][1],ans+1);
    }
    for(int i=1;i<=n;i++){
        if(vis[i][0]!=1){
            vis[i][0]=i;
            vis[i][1]=i+(p[n]-p[i]);
        }
    }
    for(int i=1;i<=n;i++){
        printf("%d %d\n",vis[i][0],vis[i][1]);
    }
}