zoukankan      html  css  js  c++  java
  • bzoj 1176: [Balkan2007]Mokia&&2683: 简单题 -- cdq分治

    2683: 简单题

    Time Limit: 50 Sec  Memory Limit: 128 MB

    Description

    你有一个N*N的棋盘,每个格子内有一个整数,初始时的时候全部为0,现在需要维护两种操作:

    命令

    参数限制

    内容

    1 x y A

    1<=x,y<=N,A是正整数

    将格子x,y里的数字加上A

    2 x1 y1 x2 y2

    1<=x1<= x2<=N

    1<=y1<= y2<=N

    输出x1 y1 x2 y2这个矩形内的数字和

    3

    终止程序

    Input

    输入文件第一行一个正整数N。
    接下来每行一个操作。
     

    Output

    对于每个2操作,输出一个对应的答案。
     

    Sample Input

    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

    1<=N<=500000,操作数不超过200000个,内存限制20M。

    对于100%的数据,操作1中的A不超过2000。

    Source

     拆点,cdq分治,第一维排序,第二维树状数组维护
     
    #include<map>
    #include<cmath>
    #include<queue>
    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    #define inf 1000000007
    #define ll long long
    #define N 2000010
    inline int rd()
    {
        int x=0,f=1;char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
        return x*f;
    }
    struct qaz{int op,x,y,v,dd;}q[N];
    bool cmp(qaz a,qaz b){return a.x==b.x?a.y<b.y:a.x<b.x;}
    int n,ans[N],m,ji[N],mm;
    int c[N];
    void add(int x,int v){for(int i=x;i<=n;i+=i&(-i)) c[i]+=v;}
    int fd(int x){int sum=0;for(int i=x;i;i-=i&(-i)) sum+=c[i];return sum;}
    void cdq(int l,int r)
    {
        if(l==r) return;
        int mid=l+r>>1;
        cdq(l,mid);cdq(mid+1,r);
        sort(q+l,q+mid+1,cmp);
        sort(q+mid+1,q+r+1,cmp);
        int i=l,j=mid+1,lst=0;
        while(j<=r)
        {
            while(q[i].op==2&&i<=mid) i++;
            while(q[j].op==1&&j<=r) j++;
            if(i<=mid&&q[i].x<=q[j].x) add(q[i].y,q[i].v),lst=i++;
            else if(j<=r) ans[q[j].dd]+=fd(q[j].y),j++;
        }
        for(i=l;i<=lst;i++) if(q[i].op==1) add(q[i].y,-q[i].v);
    }
    int main()
    {
        n=rd();
        int op,x,y,A,x2,y2;
        while(1)
        {
            op=rd();
            if(op==1)
            {
                x=rd();y=rd();A=rd();
                q[++m]=(qaz){1,x,y,A,m};
            }
            else if(op==2)
            {
                x=rd();y=rd();x2=rd();y2=rd();
                ji[++mm]=m;
                q[++m]=(qaz){2,x2,y2,0,m};
                q[++m]=(qaz){2,x-1,y-1,0,m};
                q[++m]=(qaz){2,x2,y-1,0,m};
                q[++m]=(qaz){2,x-1,y2,0,m};
            }
            else break;
        }
        cdq(1,m);
        for(int i=1,p=ji[i];i<=mm;i++,p=ji[i])
            printf("%d
    ",ans[p+1]+ans[p+2]-ans[p+3]-ans[p+4]);
        return 0;
    }
  • 相关阅读:
    iOS_文件上传进度条的实现思路-AFNettworking
    快手为什么成功
    Swift 3.1 的一些新特性
    字典类型的字符串转成字典
    phpmyadmin通过日志文件拿webshell
    计算机网络基础知识
    写一个php小脚本辅助渗透测试
    Zabbix exp编写
    sqlmap里如何添加字典
    过狗注入学习姿势分享2[投稿华盟网]
  • 原文地址:https://www.cnblogs.com/lkhll/p/7485827.html
Copyright © 2011-2022 走看看