记录一下我勇敢的尝试,和克子数据
我在题解区翻啊翻,都没有过的了的莫队,和主席树,
无奈只能看树状数组
思路都差不多:
维护区间,记录每一种在当前区间中的最后一个,
看>=l 的有多少
58分,莫队:
#include<cstdio> #include<cstdlib> #include<algorithm> #include<cmath> using namespace std; inline int read() { int x=0; char c=getchar(); while(c<'0' || c>'9' ) c=getchar(); while(c>='0'&&c<='9' ) x=(x<<3)+(x<<1)+c-'0',c=getchar(); return x; } inline void wr(int x) { if(x>=10) wr(x/10); putchar(x%10+'0'); } int n,q; const int N=1e6+3,M=1000000; int siz; int d[N],cnt[M]; struct node { int l,r,id; bool operator < (const node & o ) const { return r/siz==o.r/siz ?l<o.l : r/siz<o.r/siz; }; }ask[N]; int ans[N]; int as; void add(int x) { cnt[x]++; if(cnt[x]==1) as++; } void sub(int x) { cnt[x]--; if(cnt[x]==0) as--; } int main() { //input n=read(); siz=500; for(int i=1;i<=n;i++) d[i]=read(); q=read(); for(int i=1;i<=q;i++) ask[i].l =read(),ask[i].r =read(),ask[i].id =i; sort(ask+1,ask+q+1); int ll=1,rr=0; for(int i=1;i<=q;i++) { while(rr<ask[i].r ) add(d[++rr]); while(ll>ask[i].l ) add(d[--ll]); while(rr>ask[i].r ) sub(d[rr--]); while(ll<ask[i].l ) sub(d[ll++]); ans[ask[i].id ]=as; } for(int i=1;i<=q;i++) wr(ans[i]),putchar(' '); return 0; }
72分,主席树:
#include<cstdio> #include<cstdlib> #include<algorithm> #include<cmath> using namespace std; inline int read() { int x=0;char c=getchar(); while(c<'0' || c>'9' ) c=getchar(); while(c>='0'&&c<='9' ) x=(x<<3)+(x<<1)+c-'0',c=getchar(); return x; } inline void wr(int x) { if(x>=10) wr(x/10); putchar(x%10+'0'); } int n,q; const int N=1e6+3,Lg=20,M=1000003; int pre[M],nx[N]; int tot; int root[N]; int xh[N*Lg],ls[N*Lg],rs[N*Lg],sz[N*Lg]; void insert(int l,int r,int &x,int y,int pos) { x=++tot; sz[x]=sz[y]+1; if(l==r) return ; ls[x]=ls[y],rs[x]=rs[y]; int mid=(l+r)>>1; if(pos<=mid) insert(l,mid,ls[x],ls[y],pos); else insert(mid+1,r,rs[x],rs[y],pos); } int query(int l,int r,int x,int y,int pos) { if(l==r ) return sz[x]-sz[y]; int mid=(l+r)>>1; if(pos<=mid) return query(l,mid,ls[x],ls[y],pos) + sz[rs[x]]-sz[rs[y]]; else return query(mid+1,r,rs[x],rs[y],pos); } int main() { //input n=read(); for(int i=1;i<=n;i++) { int x=read(); if(pre[x]) nx[pre[x]]=i; pre[x]=i; } for(int i=1;i<=n;i++) if(nx[i]) insert(1,n+1,root[i],root[i-1],nx[i]); else insert(1,n+1,root[i],root[i-1],n+1); //区间中包含多少不同的贝壳,就是区间中有多少贝壳,他们的nx>r, //他们就是区间中每种贝壳的最后一个 q=read(); int l,r; while(q--) { l=read(),r=read(); wr( query(1,n+1,root[r],root[l-1],r+1)) ; putchar(' '); } return 0; }
100分,树状数组:
#include<cstdio> #include<cstdlib> #include<algorithm> using namespace std; inline int read() { int x=0;char c=getchar(); while(c<'0' || c>'9' ) c=getchar(); while(c>='0'&&c<='9' ) x=(x<<3)+(x<<1)+c-'0',c=getchar(); return x; } inline void wr(int x) { if(x>=10) wr(x/10); putchar(x%10+'0'); } int n,q; const int N=1e6+3,Lg=20,M=1000003; int d[N]; struct node { int l,r,id; bool operator < (const node & o ) const { return r<o.r; } }ask[N]; int ans[N]; int in[M]; int tr[M]; int lowbit(int x) { return x&(-x); } void add(int pos,int x) { while(pos<=N) tr[pos]+=x,pos+=lowbit(pos); } int query(int pos) { int as=0; while(pos>0) as+=tr[pos],pos-=lowbit(pos); return as; } int main() { //input n=read(); for(int i=1;i<=n;i++) d[i]=read(); q=read(); for(int i=1;i<=q;i++) ask[i].l =read() ,ask[i].r =read() ,ask[i].id =i; sort(ask+1,ask+q+1); int pre=0; for(int i=1;i<=q;i++) { for(int j=pre+1;j<=ask[i].r ;j++) { if(in[d[j]]) add(in[d[j]],-1); add(j,1),in[d[j]]=j; } pre=ask[i].r ; ans[ask[i].id ]=query(ask[i].r )-query(ask[i].l -1); } for(int i=1;i<=q;i++) wr(ans[i] ),putchar(' '); return 0; }