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]);     
  }
View Code

 

posted @ 2014-05-01 23:20  william's blog  阅读(370)  评论(0编辑  收藏  举报

adopt your own virtual pet!