BZOJ3236 [Ahoi2013]作业
无限TLE后终于A掉了....
一看就是数据结构题
没有修改操作,所以可以用莫队算法,用一个树状数组搞定
本来以为是莫队过不了
最后发现原来是自己打萎了.....
#include <cstdio> #include <iostream> #include <cstring> #include <algorithm> #include <cmath> using namespace std; const int N=2100000; const int M=2001000; int pos[N],c1[N],c2[N],c,num[N],ans1[N],ans2[N],n,m; typedef struct seg{int lx,rx,pos,a,b;}seg; seg qu[M]; int lowbit(int x){return (x&(-x));} int add(int x,int c){for (;x<=n;x+=lowbit(x)) c1[x]+=c;} int addx(int x,int c){for (;x<=n;x+=lowbit(x)) c2[x]+=c;} int sum(int x){c=0;for(;x;x-=lowbit(x))c+=c1[x];return c;} int sumx(int x){c=0;for(;x;x-=lowbit(x))c+=c2[x];return c;} int change(int x,int c) { add(num[x],c); int ans=sum(num[x])-sum(num[x-1]); if (ans==1&&c==1) addx(num[x],c); if (ans==0&&c==-1) addx(num[x],c); } int modify(seg x) { int l=x.a-1,r=x.b; ans1[x.pos]=sum(r)-sum(l); ans2[x.pos]=sumx(r)-sumx(l); } bool cmp(seg x,seg y) { if (pos[x.lx]!=pos[y.lx]) return pos[x.lx]<pos[y.lx]; return x.rx<y.rx;} int main() { //freopen("1.in","r",stdin); scanf("%d%d",&n,&m); for (int i=1;i<=n;i++) scanf("%d",&num[i]); for (int i=1;i<=m;i++) {scanf("%d%d%d%d",&qu[i].lx,&qu[i].rx,&qu[i].a,&qu[i].b); qu[i].pos=i;} int k=int(sqrt(n)); for (int i=1;i<=n;i++) pos[i]=i/k+1; sort(qu+1,qu+m+1,cmp); int l=1,r=0; for (int i=1;i<=m;i++) { seg x=qu[i]; while (r<x.rx) r++,change(r,1); while (r>x.rx) change(r,-1),r--; while (l>x.lx) l--,change(l,1); while (l<x.lx) change(l,-1),l++; modify(x);} for (int i=1;i<=m;i++) printf("%d %d\n",ans1[i],ans2[i]); }