[AHOI2013]作业 莫队 树状数组
#include<cmath> #include<cstdio> #include<algorithm> #include<string> #include<cstring> #include<iostream> #define REP(i,a,n)for(int i=a;i<=n;++i) #define CLR(d,a)memset(d,a,sizeof(d)); using namespace std; void SetIO(string a){ string in=a+".in", out=a+".out"; freopen(in.c_str(),"r",stdin); freopen(out.c_str(),"w",stdout); } void End(){ fclose(stdin); fclose(stdout); } const int maxn=300000+4; int val[maxn]; int n,m; struct Queries{ int l,r,a,b; Queries(int l=0,int r=0,int a=0,int b=0):l(l),r(r),a(a),b(b){} }ask[maxn]; void Read(){ scanf("%d%d",&n,&m); REP(i,1,n)scanf("%d",&val[i]); REP(i,1,m){ int a,b,c,d; scanf("%d%d%d%d",&a,&b,&c,&d); ask[i]=Queries(a,b,c,d); } } int block, belong[maxn], A[maxn]; int get_belong(int i){ return (i-1)/block+1; } bool cmp(int i,int j){ if(belong[ask[i].l]==belong[ask[j].l]) return ask[i].r<ask[j].r; return belong[ask[i].l]<belong[ask[j].l]; } void Build(){ block=sqrt(n); REP(i,1,n) belong[i]=get_belong(i); REP(i,1,m) A[i]=i; sort(A+1,A+1+m,cmp); } int count1[maxn]; struct BIT{ int C[2][maxn]; int lowbit(int t){return t&(-t);} void update(int pos,int o,int delta){ while(pos<=n){ C[o][pos]+=delta; pos+=lowbit(pos); } } int query(int pos,int o){ int sum=0; while(pos>0){ sum+=C[o][pos]; pos-=lowbit(pos); } return sum; } void Modify(int i,int delta){ if(i==0) return ; update(i,0,delta); count1[i]+=delta; if(delta<0 && count1[i]==0) update(i,1,delta); if(delta>0 && count1[i]==1) update(i,1,delta); } }Tree; int ans1[maxn], ans2[maxn]; void Work(){ int l=1,r=1; Tree.Modify(val[1],1); REP(i,1,m){ int cur=A[i]; int l2=ask[cur].l; int r2=ask[cur].r; if(r<r2) { ++r; while(r<=r2){ Tree.Modify(val[r],1), ++r; } --r; } else while(r>r2) { Tree.Modify(val[r],-1), --r; } if(l<l2) { while(l<l2){ Tree.Modify(val[l],-1); ++l; } } else { --l; while(l>=l2) { Tree.Modify(val[l],1), --l; } ++l; } ans1[cur]=Tree.query(ask[cur].b,0)-Tree.query(ask[cur].a-1,0); ans2[cur]=Tree.query(ask[cur].b,1)-Tree.query(ask[cur].a-1,1); } } void Print(){ REP(i,1,m) printf("%d %d\n",ans1[i],ans2[i]); } int main(){ SetIO("input"); Read(); Build(); Work(); Print(); End(); return 0; }