bzoj 1176: [Balkan2007]Mokia

Posted Soda

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了bzoj 1176: [Balkan2007]Mokia相关的知识,希望对你有一定的参考价值。

1176: [Balkan2007]Mokia

Time Limit: 30 Sec  Memory Limit: 162 MB
Submit: 2841  Solved: 1279
[Submit][Status][Discuss]

Description

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

Input

第一行两个整数,S,W;其中S为矩阵初始值;W为矩阵大小

接下来每行为一下三种输入之一(不包含引号):

"1 x y a"

"2 x1 y1 x2 y2"

"3"

输入1:你需要把(x,y)(第x行第y列)的格子权值增加a

输入2:你需要求出以左下角为(x1,y1),右上角为(x2,y2)的矩阵内所有格子的权值和,并输出

输入3:表示输入结束

Output

对于每个输入2,输出一行,即输入2的答案

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

 

保证答案不会超过int范围

#include<iostream>
#include<cstdio>
#include<algorithm>
#define maxn 200010
using namespace std;
int n,tr[2000010],ans[maxn],T,tot;
struct node{
    int x,y,op,t,z,belong;
    bool operator < (const node p)const{
        if(x!=p.x)return x<p.x;
        if(y!=p.y)return y<p.y;
        return op<p.op;
    }
}q[maxn],tmp[maxn];
void modify(int x,int delta){
    while(x<=n){
        tr[x]+=delta;
        x+=x&(-x);
    }
}
int query(int x){
    int res=0;
    while(x){
        res+=tr[x];
        x-=x&(-x);
    }
    return res;
}
void work(int l,int r){
    if(l==r)return;
    int mid=l+r>>1;
    for(int i=l;i<=r;i++){
        if(q[i].t<=mid&&q[i].op==1)modify(q[i].y,q[i].z);
        if(q[i].t>mid&&q[i].op==2)ans[q[i].belong]+=query(q[i].y)*q[i].z;
    }
    for(int i=l;i<=r;i++)
        if(q[i].t<=mid&&q[i].op==1)modify(q[i].y,-q[i].z);
    int l1=l,l2=mid+1;
    for(int i=l;i<=r;i++){
        if(q[i].t<=mid)tmp[l1++]=q[i];
        else tmp[l2++]=q[i];
    }
    for(int i=l;i<=r;i++)q[i]=tmp[i];
    work(l,mid);work(mid+1,r);
}
int main(){
    scanf("%d",&n);scanf("%d",&n);
    int opt,x,y,z,x1,x2,y1,y2;
    while(1){
        scanf("%d",&opt);
        if(opt==1){
            scanf("%d%d%d",&x,&y,&z);
            q[++tot].t=tot;q[tot].x=x;q[tot].y=y;q[tot].op=1;q[tot].z=z;
        }
        if(opt==2){
            scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
            q[++tot].t=tot;q[tot].x=x1-1;q[tot].y=y1-1;q[tot].z=1;q[tot].op=2;q[tot].belong=++T;
            q[++tot].t=tot;q[tot].x=x1-1;q[tot].y=y2;q[tot].z=-1;q[tot].op=2;q[tot].belong=T;
            q[++tot].t=tot;q[tot].x=x2;q[tot].y=y1-1;q[tot].z=-1;q[tot].op=2;q[tot].belong=T;
            q[++tot].t=tot;q[tot].x=x2;q[tot].y=y2;q[tot].z=1;q[tot].op=2;q[tot].belong=T;
        }
        if(opt==3)break;
    }
    sort(q+1,q+tot+1);
    work(1,tot);
    for(int i=1;i<=T;i++)printf("%d\n",ans[i]);
    return 0;
}

 

以上是关于bzoj 1176: [Balkan2007]Mokia的主要内容,如果未能解决你的问题,请参考以下文章

[BZOJ1176][Balkan2007]Mokia cdq+树状数组

bzoj千题计划144:bzoj1176: [Balkan2007]Mokia

Bzoj1176 [Balkan2007]Mokia

BZOJ1176:[Balkan2007]Mokia——题解

bzoj1176[Balkan2007]Mokia/bzoj2683简单题

BZOJ 1176: [Balkan2007]Mokia