• BZOJ 1176([Balkan2007]Mokia-CDQ分治-分治询问)


    1176: [Balkan2007]Mokia

    Time Limit: 30 Sec   Memory Limit: 162 MB
    Submit: 185   Solved: 94
    [ Submit][ Status]

    Description

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

    Input

     

    Output

     

    Sample Input

    0 4
    1 2 3 3
    2 1 1 3 3
    1 2 2 2
    2 2 2 3 4
    3

    Sample Output

    3
    5

    HINT

    Input file Output file Meaning
    0 4 Table size is , filled with zeroes.

    1 2 3 3 Add 3 customers at (2, 3).
    2 1 1 3 3 Query sum of rectangle , .

    3 Answer.
    1 2 2 2 Add 2 customers at (2, 2).
    2 2 2 3 4 Query sum of rectangle , .

    5 Answer
    3 Exit your program.



    裸CDQ...1A

    注意几个关键部分的写法

    步骤:

    1.读入询问,按x排序

    2.将[L,R]中的数分为前部分操作,后部分操作(各部分仍保持X升序)

    3.将前面对后面的影响记录ans

    4.复原影响

    5.递归[L,M],[M+1,R]


    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #include<functional>
    #include<cmath>
    #include<cctype>
    #include<cassert>
    #include<climits>
    using namespace std;
    #define For(i,n) for(int i=1;i<=n;i++)
    #define Rep(i,n) for(int i=0;i<n;i++)
    #define Fork(i,k,n) for(int i=k;i<=n;i++)
    #define ForD(i,n) for(int i=n;i;i--)
    #define Forp(x) for(int p=pre[x];p;p=next[p])
    #define RepD(i,n) for(int i=n;i>=0;i--)
    #define MEM(a) memset(a,0,sizeof(a))
    #define MEMI(a) memset(a,127,sizeof(a))
    #define MEMi(a) memset(a,128,sizeof(a))
    #define INF (2139062143)
    #define F (1000000009)
    #define MAXM (640000+10)
    #define MAXQ (10000+10)
    #define MAXN (2000000+10) 
    typedef long long ll;
    int n,m,q;
    ll ans[MAXQ];
    struct comm
    {
       int no,x,y,v,q,type;
       comm():no(0),x(0),y(0),v(0),q(0),type(0){}
       comm(int _no,int _x,int _y,int _v,int _q,int _type):no(_no),x(_x),y(_y),v(_v),q(_q),type(_type){}
       friend bool operator<(comm a,comm b){return a.x<b.x;}      
    }ask[MAXM];
    struct arr_tree
    {
       ll a[MAXN];
       arr_tree(){memset(a,0,sizeof(a));}
       void add(int x,ll c)
       {
          for(int i=x;i<=n;i+=i&(-i)) a[i]+=c;
       }
       int qur(int x)
       {
          ll ans=0;
          for(int i=x;i;i-=i&(-i)) ans+=a[i];
          return ans;   
       }
       void clear()
       {
          memset(a,0,sizeof(a));
       }
    }T;
    comm tmp[MAXM];
    void solve(int l,int r)
    {
       if (l==r) return;
       int m=l+r>>1;
       int s1=l-1,s2=m;
       Fork(i,l,r) tmp[ask[i].no<=m?++s1:++s2]= ask[i];
       memcpy(ask+l,tmp+l,sizeof(comm)*(r-l+1));
       int now=l;
       Fork(i,m+1,r) //遍历询问 
       {
          if (ask[i].type==2)
          {
             while (ask[now].x<=ask[i].x&&now<=m)
             {
                if (ask[now].type==1) T.add(ask[now].y,ask[now].v);
                now++;
             }
             ans[ask[i].q]+=ask[i].v*T.qur(ask[i].y);         
          }
       }
       now--;
       while (l<=now) {if (ask[now].type==1) T.add(ask[now].y,-ask[now].v);now--;}
       solve(l,m),solve(m+1,r);
    }
    bool work()
    {
       scanf("%d",&n);
       int type,no=0,x,y,x1,y1,x2,y2,v,q=0;
       memset(ans,0,sizeof(ans));T.clear();
       while (scanf("%d",&type))
       {
          if (type==0||type==3) break;
          else if (type==1)
          {
             scanf("%d%d%d",&x,&y,&v);
             no++;ask[no]=comm(no,x,y,v,0,1);
          }
          else if (type==2)
          {
             scanf("%d%d%d%d",&x1,&y1,&x2,&y2);q++;
             no++;ask[no]=comm(no,x1-1,y1-1,1,q,2);
             no++;ask[no]=comm(no,x2,y2,1,q,2);
             no++;ask[no]=comm(no,x1-1,y2,-1,q,2);
             no++;ask[no]=comm(no,x2,y1-1,-1,q,2);         
          }
       }
       sort(ask+1,ask+1+no);
       solve(1,no);
       For(i,q) cout<<ans[i]<<endl;
       return type==0;
    }
    int main()
    {
       //freopen("bzoj1176.in","r",stdin);
       int type;
       scanf("%d",&type);if (type==3) return 0;
       while (work());
       //cout<<"END"<<endl;while (1);
       return 0;
    }
    





  • 相关阅读:
    phpcms 任意位置获取用户头像
    php微信公众帐号发送红包
    nginx解决502错误
    phpcms v9 万能字段使用
    0转换为万
    温故而知新(三)
    温故而知新(一)
    基础积累,来自其他网站的链接
    GCD多线程 在子线程中获取网络图片 在主线程更新
    iOS9 中的一些适配问题
  • 原文地址:https://www.cnblogs.com/dyllove98/p/3186980.html
Copyright © 2020-2023  润新知