2018牛客多校1 - J Different Integers 莫队/主席树签到

题意:给出n<5e4,a[1...n],单次1e5总次1e6次查询除去区间(L,R)的数的个数

开场5分钟:莫队是不可能莫队的,这道题是不可能莫队的

最后1小时:真香

具体操作没啥特别的,注意一下add和del是和实际相反的操作,以及开区间特判

然而这是卡着过去的..

正解用裸主席树或其他dsa,只需把数组翻倍再拼接就好(我好菜啊

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<string>
#include<vector>
#include<stack>
#include<queue>
#include<set>
#include<map>
#define rep(i,j,k) for(register int i=j;i<=k;i++)
#define rrep(i,j,k) for(register int i=j;i>=k;i--)
#define erep(i,u) for(register int i=head[u];~i;i=nxt[i])
#define print(a) printf("%lld",(ll)a)
#define println(a) printf("%lld\n",(ll)a)
using namespace std;
const int MAXN = 1e5+11;
typedef long long ll;
ll read(){
    ll x=0,f=1;register 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;
}
int freq[MAXN],cur[MAXN],curfreq[MAXN],f[MAXN];
int a[MAXN],ans[MAXN];
int tf[MAXN];
//,head[MAXN],tail[MAXN],ans[MAXN];
int n,m,size;
//int sumL[MAXN],sumR[MAXN];
struct QQQ{
    int l,r,pos,flag;
}Q[MAXN];
bool cmp(QQQ a,QQQ b){
    if(a.l/size!=b.l/size) return a.l/size<b.l/size;
    else return a.r<b.r;
} 

int L,R,ANS;
void add(int cur){
    //if(f[a[cur]]==0) ANS++;
    f[a[cur]]--;
    if(f[a[cur]]==0) ANS--;
}
void del(int cur){
    if(f[a[cur]]==0) ANS++;
    f[a[cur]]++;
}
int main(){
    while(~scanf("%d%d",&n,&m)){
        size=sqrt(n)+1;
        rep(i,1,n) a[i]=read();
        //memset(freq,0,sizeof freq);
        //rep(i,1,n) freq[a[i]]++;
        rep(i,1,m){
            int l=read();
            int r=read();
            Q[i].l=l+1;
            Q[i].r=r-1;
            Q[i].pos=i;
            if(l+1==r) Q[i].flag=0;
            else Q[i].flag=1;
        }
        sort(Q+1,Q+1+m,cmp);
        
        L=1,R=n; ANS=0;
        int AANS=0;
        memset(tf,0,sizeof tf);
        rep(i,1,n){
            if(tf[a[i]]==0) AANS++;
            tf[a[i]]++;
        }

        memset(f,0,sizeof f);
        // rep(i,1,n){
        //     if(f[a[i]]==0) ANS++;
        //     f[a[i]]++;
        // }
        rep(i,1,m){ 
            
            if(Q[i].flag)while(L>Q[i].l){
                L--;
                add(L);
            }
            if(Q[i].flag)while(R<Q[i].r){
                R++;
                add(R);
            }
            if(Q[i].flag)while(L<Q[i].l){
                del(L);
                L++;
            }
            if(Q[i].flag)while(R>Q[i].r){
                del(R);
                R--;
            }
            if(Q[i].flag) ans[Q[i].pos]=ANS;
            else ans[Q[i].pos]=AANS;
        }
        rep(i,1,m){
            printf("%d\n",ans[i]);
        }
    }
    return 0;
}
posted @ 2018-07-19 17:53  Caturra  阅读(320)  评论(0编辑  收藏  举报