zoukankan      html  css  js  c++  java
  • bzoj2683

    2683: 简单题

    Time Limit: 50 Sec  Memory Limit: 128 MB
    Submit: 1018  Solved: 413
    [Submit][Status][Discuss]

    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。
    双倍经验
    看到了无聊交了一下。。。
    #include<cstdio>
    #include<vector>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    const int N=2000010;
    struct data
    {
        int x,y,dir,pos,type,delta;
    }event[N];
    int n,size,w,s,m,pos,opt;
    vector<data> c;
    int tree[N],ans[N];
    bool cp(data x,data y)
    {
        if(x.x!=y.x) return x.x<y.x;
        if(x.y!=y.y) return x.y<y.y;
        return x.type<y.type;
    }
    int lowbit(int x)
    {
        return x&(-x);
    }
    void update(int pos,int delta)
    {
        for(int i=pos;i<=N+1;i+=lowbit(i))
        {
            tree[i]+=delta;
        }
    }
    int sum(int pos)
    {
        int ret=0;
        for(int i=pos;i>0;i-=lowbit(i))
        {
            ret+=tree[i];
        }
        return ret;
    }
    
    void cdq(int l,int r)
    {
        if(l>=r) return; 
        int mid=(l+r)/2;
        cdq(l,mid); 
        cdq(mid+1,r);
        c.clear();
        for(int i=l;i<=mid;i++)
            if(event[i].type==1) c.push_back(event[i]);
        for(int i=mid+1;i<=r;i++)
            if(event[i].type==2) c.push_back(event[i]);
        sort(c.begin(),c.end(),cp);
        for(int i=0;i<c.size();i++)
        {
    //        printf("type=%d pos=%d
    ",c[i].type,c[i].pos);
            if(c[i].type==1) 
              update(c[i].y,c[i].delta);
            if(c[i].type==2) 
            {
                ans[c[i].pos]+=sum(c[i].y)*c[i].dir;
    //            printf("%d
    ",sum(c[i].y));
            }
        }
        for(int i=0;i<c.size();i++)
            if(c[i].type==1) update(c[i].y,-c[i].delta);
    }
    
    void addquery(int x,int y,int dir)
    {
        event[++m].x=x; event[m].y=y; 
        event[m].dir=dir; event[m].pos=pos;
        event[m].type=2;
    }
    
    int main()
    {
        scanf("%d",&s);        
        while(scanf("%d",&opt))
        {
            if(opt==3) break;
            int x,y,delta,x1,y1,x2,y2;
            if(opt==1)
            {
                scanf("%d%d%d",&x,&y,&delta);
                x++; 
                y++;
                m++;
                event[m].type=opt; 
                event[m].x=x; 
                event[m].y=y; 
                event[m].delta=delta;
            }
            else if(opt==2)
            {
                ++pos;
                //ans[++pos]+=abs(x1-x2)*abs(y1-y2)*s;
                scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
                x1++; x2++; y1++; y2++;
                addquery(x1-1,y1-1,1);
                addquery(x2,y2,1);
                addquery(x1-1,y2,-1);
                addquery(x2,y1-1,-1);
            }
        }
        cdq(1,m);
        for(int i=1;i<=pos;i++)
        {
            printf("%d
    ",ans[i]);
        }
        return 0;
    }
  • 相关阅读:
    网络流24题之汽车加油行驶问题
    「CodeChef
    「HNOI 2016」 序列
    「HNOI 2015」实验比较
    「JXOI 2018」 排序问题
    「HNOI 2014」 江南乐
    「HNOI 2015」亚瑟王
    「HNOI 2015」菜肴制作
    「HNOI 2015」落忆枫音
    蓝桥杯 方格分割
  • 原文地址:https://www.cnblogs.com/19992147orz/p/6185249.html
Copyright © 2011-2022 走看看