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\n",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\n",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\n",ans[i]);
    }
    return 0;
}
时间: 2024-10-29 06:38:20

bzoj2683的相关文章

[BZOJ2683][BZOJ4066]简单题

试题描述 你有一个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 无 终止程序 输入 输入文件第一行一个正整数N. 接下来每行一个操作.每条命令除第一个数字之外, 均要异或上一次输出的答案last

【bzoj1176】[Balkan2007]Mokia/【bzoj2683】简单题

bzoj1176 题目描述 维护一个W*W的矩阵,初始值均为S(题目描述有误,这里的S没有任何作用!).每次操作可以增加某格子的权值,或询问某子矩阵的总权值.修改操作数M<=160000,询问数Q<=10000,W<=2000000. 输入 第一行两个整数,S,W;其中S为矩阵初始值;W为矩阵大小接下来每行为一下三种输入之一(不包含引号):1 x y a2 x1 y1 x2 y23输入1:你需要把(x,y)(第x行第y列)的格子权值增加a输入2:你需要求出以左下角为(x1,y1),右上角

BZOJ2683: 简单题(CDQ分治 + 树状数组)

BZOJ2683: 简单题(CDQ分治 + 树状数组) 题意: 你有一个\(N*N\)的棋盘,每个格子内有一个整数,初始时的时候全部为\(0\),现在需要维护两种操作: 命令 参数限制 内容 \(1\ x\ y\ A\) \(1\le x,y \le N\),A是正整数 将格子\(x,y\)里的数字加上\(A\) \(2\ x1\ y1\ x2\ y2\) \(1\le x1\le x2\le N,1\le y1\le y2\le N\) 输出\(x1\ y1\ x2\ y2\)这个矩形内的数字

bzoj2683: 简单题

CDQ分治,然而超过内存了 CDQ分治的思想还是很有趣的. http://www.lydsy.com/JudgeOnline/problem.php?id=2683 /************************************************************** Problem: 2683 User: 1349367067 Language: C++ Result: Accepted Time:7344 ms Memory:45028 kb ************

【BZOJ2683】简单题

cdq分治妙啊 (被改过题面的)原题: dydxh所出的题目是这样的:有一个N*N矩阵,给出一系列的修改和询问,修改是这样的:将(x,y)中的数字加上k,而询问是这样的:求(x1,y1)到(x2,y2)这个子矩阵内所有数字的和.虽然这么高级的数据结构题mzx这种菜逼当然不会,但是由于dydxh给mzx留了一条没有强制在线的生路,所以mzx决定挑战一下这道题. 1<=N<=500000,操作数不超过200000个,操作1中的k为正整数,且不超过2000 思路很妙,知道为什么要这样做但是感觉考场上

bzoj2683简单题

2683: 简单题 Time Limit: 50 Sec  Memory Limit: 128 MB Submit: 738  Solved: 307 [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<

Bzoj2683 简单题 [CDQ分治]

Time Limit: 50 Sec  Memory Limit: 128 MBSubmit: 1071  Solved: 428 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这个矩形

【BZOJ2683】简单题 [分治][树状数组]

简单题 Time Limit: 50 Sec  Memory Limit: 128 MB[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

bzoj2683简单题 cdq分治

2683: 简单题 Time Limit: 50 Sec  Memory Limit: 128 MBSubmit: 1803  Solved: 731[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<