设为首页 加入收藏

TOP

BZOJ 1176 [Balkan2007]Mokia CDQ分治
2015-07-20 17:35:21 来源: 作者: 【 】 浏览:2
Tags:BZOJ 1176 Balkan2007 Mokia CDQ分治

题目大意:

维护一个W*W的矩阵,初始值均为S.每次操作可以增加某格子的权值,或询问某子矩阵的总权值.修改操作数M<=160000,询问数Q<=10000,W<=2000000.

POJ1195的加强版

没记错的话上午这题还没有中文题目描述的说0.0 好迅速

首先这题看到W就知道二维树状数组挂了 看到M就发现离散化了也搞不了 0.0

这题似乎是CDQ分治被发现之后第二个解决的题目。。。不过只有会员才知道的世界,今天反应过来刷刷。。。

修改和询问放在一起分治,一个询问拆分成4个,树状数组处理,每层分治处理左区间中修改对右区间的询问即可

此外题目描述有误,S不是初值,是操作的编号,我还纳闷怎么没加初值就AC了0.0 所以S恒为0,不用管了

#include
  
   
#include
   
     #include
    
      #include
     
       #define M 2002002 using namespace std; struct abcd{ int x,y,num,pos,ans; abcd(){} abcd(int X,int Y,int Num); bool operator <(const abcd &y)const { return x < y.x; } }q[200200],nq[200200]; int num,w,n,ans; int c[M],tim[M],T; void update(int x,int y) { for(;x<=w;x+=x&-x) { if(tim[x]!=T) c[x]=0; tim[x]=T; c[x]+=y; } } int getans(int x) { int re=0; for(;x;x-=x&-x) if(tim[x]==T) re+=c[x]; return re; } bool cmp(const abcd &x,const abcd &y) { return x.pos < y.pos; } abcd :: abcd(int X,int Y,int Num) { x=X; y=Y; num=Num; pos=n; ans=0; } void CDQ(int l,int r) { int i,j,mid=l+r>>1; int l1=l,l2=mid+1; if(l==r) return ; for(i=l;i<=r;i++) { if(q[i].pos<=mid) nq[l1++]=q[i]; else nq[l2++]=q[i]; } memcpy( q+l , nq+l , sizeof(q[0])*(r-l+1) ); CDQ(l,mid); j=l;++T; for(i=mid+1;i<=r;i++) { for(;q[j].x<=q[i].x&&j<=mid;j++) if(q[j].num!=19980402) update(q[j].y,q[j].num); if(q[i].num==19980402) q[i].ans+=getans(q[i].y); } CDQ(mid+1,r); l1=l;l2=mid+1; for(i=l;i<=r;i++) { if(q[l1]
      
       r) nq[i]=q[l1++]; else nq[i]=q[l2++]; } memcpy( q+l , nq+l , sizeof(q[0])*(r-l+1) ); } int main() { int i,p,x,y,z,x1,y1,x2,y2; cin>>num>>w; while(scanf("%d",&p),p^3) { if(p==1) scanf("%d%d%d",&x,&y,&z),q[++n]=abcd(x,y,z); else { scanf("%d%d%d%d",&x1,&y1,&x2,&y2); q[++n]=abcd(x1-1,y1-1,19980402); q[++n]=abcd(x1-1,y2,19980402); q[++n]=abcd(x2,y1-1,19980402); q[++n]=abcd(x2,y2,19980402); } } sort(q+1,q+n+1); CDQ(1,n); sort(q+1,q+n+1,cmp); for(i=1;i<=n;i++) if(q[i].num==19980402) { ans=0; ans+=q[i++].ans; ans-=q[i++].ans; ans-=q[i++].ans; ans+=q[i ].ans; printf("%d\n",ans); } } 
      
     
    
   
  


】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇hdu 4407 Sum 容斥+离线 下一篇NYOJ 24 素数距离问题

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容:

·有没有适合新手练习 (2025-12-26 01:48:47)
·用清华镜像网怎么下 (2025-12-26 01:48:44)
·请比较Python和R语言 (2025-12-26 01:48:42)
·JAVA现在的就业环境 (2025-12-26 01:19:24)
·最好的java反编译工 (2025-12-26 01:19:21)