zoukankan      html  css  js  c++  java
  • bzoj 1176 Mokia(CDQ分治,BIT)

      

    【题目链接】

      http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=96974

    【题意】

        定义查询操作与修改操作:1 x y z 为将格子(x,y)修改为z;2 x1 y1 x2 y2为查询以(x1,y1)为左上(x2,y2)为右下的子矩阵之和。

    【思路】

        cdq分治。

        矩阵初始值都为s,所以先不考虑。

        首先明确每一个修改操作都互不影响。然后把每一个对子矩阵的询问操作差分为对四个点的“前缀和”操作。

        先把所有的操作按照x升序排列。进行cdq分治。

        定义solve(l,r)为解决查询顺序在l,r区间内的操作,且在solve结束后保证区间按照x的递增排列。

      1) 将区间按照查询先后顺序重排

      2) Solve(l,mid)

      3) 计算左区间对右区间的贡献。这时候左区间是按照x升序排列的,右区间是按照查询先后排列的,这样正好既可以保证求贡献时左区间x的单调与递归右区间时右区间内所有的查询都在。对于右区间的i,将左区间内x所有小于它的加入BIT,维护区间和,如果i是询问则查询BIT中所有y小于它的z之和。

      4) Solve(mid+1,r)

      5) 恢复区间,按照x升序排列

        最后答案加上矩阵的s即可。

      BIT的清理也可通过加时间戳的方式做到。

    【代码】

      1 #include<cstdio>
      2 #include<cstring>
      3 #include<iostream>
      4 #include<algorithm>
      5 using namespace std;
      6 
      7 const int N = 2*1e6+10;
      8 const int inf = 1e9+7;
      9 
     10 int n,sz,s,w;
     11 int C[N],flag[N],T,tmp[N];
     12 
     13 struct Node {
     14     int x,y,z,pos,ans;
     15     bool operator<(const Node& rhs) const{
     16         return x<rhs.x;
     17     }
     18     Node(int x=0,int y=0,int z=0) {
     19         this->x=x,this->y=y,this->z=z;
     20         pos=sz; ans=0;
     21     }
     22 }q[N],t[N];
     23 bool cmp(const Node& x,const Node& y)
     24 {
     25     return x.pos<y.pos;
     26 }
     27 
     28 void add(int x,int v)
     29 {
     30     for(;x<=w;x+=x&-x)
     31         if(flag[x]!=T) flag[x]=T,C[x]=v;
     32         else C[x]+=v;
     33 }
     34 int query(int x)
     35 {
     36     int res=0;
     37     for(;x;x-=x&-x)
     38         if(flag[x]==T) res+=C[x];
     39     return res;
     40 }
     41 
     42 void solve(int l,int r)
     43 {
     44     if(l==r) return ;
     45     int mid=(l+r)>>1;
     46     int l1=l,l2=mid+1,i,j;
     47     for(i=l;i<=r;i++) {
     48         if(q[i].pos<=mid) t[l1++]=q[i];
     49         else t[l2++]=q[i];
     50     }
     51     memcpy(q+l,t+l,sizeof(q[0])*(r-l+1));
     52     solve(l,mid);
     53     j=l; T++;
     54     for(i=mid+1;i<=r;i++) {
     55         for(;j<=mid&&q[j].x<=q[i].x;j++)
     56             if(q[j].z!=-inf) add(q[j].y,q[j].z);
     57         if(q[i].z==-inf) q[i].ans+=query(q[i].y);
     58     }
     59     solve(mid+1,r);
     60     l1=l,l2=mid+1; int now=l;
     61     while(l1<=mid||l2<=r) {
     62         if(l2>r||l1<=mid&&q[l1]<q[l2]) t[now++]=q[l1++];
     63         else t[now++]=q[l2++];
     64     }
     65     memcpy(q+l,t+l,sizeof(q[0])*(r-l+1));
     66 }
     67 
     68 void read(int &x)
     69 {
     70     char c=getchar(); x=0;int f=1;
     71     while(!isdigit(c)){ if(c=='-')f=-1; c=getchar(); }
     72     while(isdigit(c)) x=x*10+c-'0' , c=getchar();
     73     x*=f;
     74 }
     75 
     76 int main()
     77 {
     78     read(s),read(w);
     79     int op,x1,y1,x2,y2,z;
     80     while(read(op),op!=3)
     81     {
     82         if(op==1) {
     83             read(x1),read(y1),read(z);
     84             q[++sz]=(Node){x1,y1,z};
     85         } else {
     86             read(x1),read(y1),read(x2),read(y2);
     87             q[++sz]=Node(x1-1,y1-1,-inf);
     88             tmp[sz]=abs(x1-x2+1)*abs(y1-y2+1)*s;
     89             q[++sz]=Node(x1-1,y2,-inf);
     90             q[++sz]=Node(x2,y1-1,-inf);
     91             q[++sz]=Node(x2,y2,-inf);
     92         }
     93     }
     94     sort(q+1,q+sz+1);
     95     solve(1,sz);
     96     sort(q+1,q+sz+1,cmp);
     97     for(int i=1;i<=sz;i++) if(q[i].z==-inf) {
     98         int ans=tmp[i];
     99         ans+=q[i++].ans;
    100         ans-=q[i++].ans;
    101         ans-=q[i++].ans;
    102         ans+=q[i++].ans;
    103         i--;
    104         printf("%d
    ",ans);
    105     }
    106     return 0;
    107 }

      ps:鄙人并非权限汪,如代码不能AC概不负责 :)

  • 相关阅读:
    Unix进程和线程管理及其异同
    UnixIPC之共享内存
    Unix/Linux常用文件操作
    java中int和Integer比较
    JAVA四种引用类型
    JAVA-Exception&Error
    JAVA特性-跨平台/面向对象
    JAVA单向链表实现
    linux安装及配置c++的opencv库
    static_cast、const_cast、dynamic_cast、reinterpret_cast
  • 原文地址:https://www.cnblogs.com/lidaxin/p/5257561.html
Copyright © 2011-2022 走看看