莫队+树状数组+读入优化 75s+AC(PS:我居然先写的线段树)code:
#include<iostream> #include<algorithm> #include<cmath> #include<cstdio> #include<cstring> #define mid (l+r)/2 #define lch i<<1,l,mid #define rch i<<1|1,mid+1,r using namespace std; char * p=(char *)malloc(50000000); inline int in(){ int x=0; while(*p<'0'||*p>'9')++p; while(*p>='0'&&*p<='9')x=x*10+*p++-'0'; return x; } struct hp{ int l,r,a,b,st,num; }qst[1000001]; int ans[1000001][2]; int node[400001][2]; int vis[1000001]; int n,m,a[100001],L,R,size; int cmp(const hp &a,const hp &b) { if ((a.st<b.st)||(a.st==b.st&&a.r<b.r)) return 1; else return 0; } int lowbit(int x){return x&(-x); } inline void bit_ins0(int x,int a) { while (x<=n) {node[x][0]+=a; x+=lowbit(x);} } inline void bit_ins1(int x,int a) { while (x<=n) {node[x][1]+=a; x+=lowbit(x);} } inline int query0(int x) { int ans=0; while (x) { ans+=node[x][0]; x-=lowbit(x); } return ans; } inline int query1(int x) { int ans=0; while (x) { ans+=node[x][1]; x-=lowbit(x); } return ans; } inline void work(int i) { int l=qst[i].l,r=qst[i].r; while (L<l) { bit_ins0(a[L],-1); if (vis[a[L]]==1) bit_ins1(a[L],-1); vis[a[L]]--; L++; } while (L>l) { L--; bit_ins0(a[L],1); if (vis[a[L]]==0) bit_ins1(a[L],1); vis[a[L]]++; } while (R<r) { R++; bit_ins0(a[R],1); if (vis[a[R]]==0) bit_ins1(a[R],1); vis[a[R]]++; } while (R>r) { bit_ins0(a[R],-1); if (vis[a[R]]==1) bit_ins1(a[R],-1); vis[a[R]]--; R--; } ans[qst[i].num][0]=query0(qst[i].b)-query0(qst[i].a-1); ans[qst[i].num][1]=query1(qst[i].b)-query1(qst[i].a-1); } int main() { int i,per; fread(p,1,50000000,stdin); n=in(),m=in(); for (i=1;i<=n;++i)a[i]=in(); per=sqrt(n); size=n; for (i=1;i<=m;++i) { qst[i].l=in(),qst[i].r=in(),qst[i].a=in(),qst[i].b=in(); qst[i].st=(qst[i].l/per)+1; qst[i].num=i; } sort(qst+1,qst+m+1,cmp); for (i=qst[1].l;i<=qst[1].r;++i) { bit_ins0(a[i],1); if (vis[a[i]]==0) bit_ins1(a[i],1); vis[a[i]]++; } ans[qst[1].num][0]=query0(qst[1].b)-query0(qst[1].a-1); ans[qst[1].num][1]=query1(qst[1].b)-query1(qst[1].a-1); L=qst[1].l; R=qst[1].r; for (i=2;i<=m;++i) work(i); for (i=1;i<=m;++i) printf("%d %d\n",ans[i][0],ans[i][1]); }