bzoj3236 作业 莫队+树状数组

来源:互联网 发布:js 数组存在值 编辑:程序博客网 时间:2024/06/05 14:05

莫队+树状数组

#include<cstdio>#include<cstring>#include<iostream>#include<algorithm>#include<cmath>#define N 100055#define M 1000066using namespace std;int gy[N],be[N],c[M],cc[M],n,m,nn,maxn,tot,num[N];struct Query{int l,r,a,b,id,ans1,ans2;}qr[M];bool cmp1(Query a,Query b){if(be[a.l]==be[b.l])return a.r<b.r;return be[a.l]<be[b.l];}bool cmp2(Query a,Query b){return a.id<b.id;}int lowbit(int x){return x&(-x);}void add(int x,int y){int xx=x;if(y==1&&++num[xx]==1){while(xx<=maxn){cc[xx]++;xx+=lowbit(xx);}}if(y==-1&&--num[xx]==0){while(xx<=maxn){cc[xx]--;xx+=lowbit(xx);}}while(x<=maxn){c[x]+=y;x+=lowbit(x);}}int query(int x){if(x>maxn) x=maxn;int ans=0;while(x){ans+=c[x];x-=lowbit(x);}return ans;}int query1(int x){if(x>maxn) x=maxn;int ans=0;while(x){ans+=cc[x];x-=lowbit(x);}return ans;}void work(){int l=1,r=0;tot=0;for(int i=1;i<=m;i++){while(l<qr[i].l) add(gy[l++],-1);while(l>qr[i].l) add(gy[--l],1);while(r<qr[i].r) add(gy[++r],1);while(r>qr[i].r) add(gy[r--],-1);qr[i].ans1=query(qr[i].b)-query(qr[i].a-1);qr[i].ans2=query1(qr[i].b)-query1(qr[i].a-1);}}int main(){scanf("%d%d",&n,&m); nn=(int)sqrt(n);for(int i=1;i<=n;i++){scanf("%d",&gy[i]);be[i]=(i-1)/nn+1;maxn=max(maxn,gy[i]);}int l,r,a,b;for(int i=1;i<=m;i++){scanf("%d%d%d%d",&l,&r,&a,&b);qr[i].l=l; qr[i].r=r;qr[i].a=a; qr[i].b=b;qr[i].id=i;}sort(qr+1,qr+m+1,cmp1);work();sort(qr+1,qr+m+1,cmp2);for(int i=1;i<=m;i++)printf("%d %d\n",qr[i].ans1,qr[i].ans2);return 0;}


原创粉丝点击