hihocoder#1336 : Matrix Sum(二维线段树)

来源:互联网 发布:淘宝2016双十一交易额 编辑:程序博客网 时间:2024/05/20 09:24
时间限制:10000ms
单点时限:1000ms
内存限制:256MB

描述

You are given an N × N matrix. At the beginning every element is 0. Write a program supporting 2 operations:

 1. Add x y value: Add value to the element Axy. (Subscripts starts from 0

2. Sum x1 y1 x2 y1: Return the sum of every element Axy for x1 ≤ x ≤ x2y1 ≤ y ≤ y2.

输入

The first line contains 2 integers N and M, the size of the matrix and the number of operations.

Each of the following M line contains an operation.

1 ≤ N ≤ 1000, 1 ≤ M ≤ 100000

For each Add operation: 0 ≤ x < N, 0 ≤ y < N, -1000000 ≤ value ≤ 1000000

For each Sum operation: 0 ≤ x1 ≤ x2 < N, 0 ≤ y1 ≤ y2 < N 

输出

For each Sum operation output a non-negative number denoting the sum modulo 109+7.

样例输入
5 8Add 0 0 1Sum 0 0 1 1Add 1 1 1Sum 0 0 1 1Add 2 2 1Add 3 3 1Add 4 4 -1Sum 0 0 4 4 
样例输出
123 
思路:可以用二维树状数组来做,代码又短又简洁。不过最近在练习二维线段树的题,就用二维线段树写了。。有问题的地方欢迎指出。对了,此题有一个小坑,要仔细读题,For each Sum operation output a non-negative (是一个非负整数,所以答案要加上1e9+7后再取模) number。
#include<bits/stdc++.h>using namespace std;const int MOD=1e9+7;long long sum[4001][4001];int n;void cloadd(int tag,int p,int k,int l,int r,int y,long long val){    if(l==r)    {        if(tag)sum[p][k]=(sum[p][k]+val)%MOD;        else sum[p][k]=(sum[2*p][k]+sum[2*p+1][k])%MOD;        return;    }    if(y<=(l+r)/2)cloadd(tag,p,2*k,l,(l+r)/2,y,val);    else cloadd(tag,p,2*k+1,(l+r)/2+1,r,y,val);    if(tag)sum[p][k]=(sum[p][2*k]+sum[p][2*k+1])%MOD;    else sum[p][k]=(sum[2*p][k]+sum[2*p+1][k])%MOD;}void rowadd(int k,int l,int r,int x,int y,long long val){    if(x==l&&x==r){cloadd(1,k,1,1,n,y,val);return;}    if(x<=(l+r)/2)rowadd(2*k,l,(l+r)/2,x,y,val);    else rowadd(2*k+1,(l+r)/2+1,r,x,y,val);    cloadd(0,k,1,1,n,y,val);}long long cloask(int p,int k,int l,int r,int y,int y1){    if(y<=l&&y1>=r)return sum[p][k]%MOD;    if(y1<=(l+r)/2)return cloask(p,2*k,l,(l+r)/2,y,y1)%MOD;    else if(y>=(l+r)/2+1)return cloask(p,2*k+1,(l+r)/2+1,r,y,y1)%MOD;    return (cloask(p,2*k,l,(l+r)/2,y,(l+r)/2)+cloask(p,2*k+1,(l+r)/2+1,r,(l+r)/2+1,y1))%MOD;}long long rowask(int k,int l,int r,int x,int y,int x1,int y1){    if(x==l&&x1==r)return cloask(k,1,1,n,y,y1)%MOD;    if(x1<=(l+r)/2)return rowask(2*k,l,(l+r)/2,x,y,x1,y1)%MOD;    else if(x>=(l+r)/2+1)return rowask(2*k+1,(l+r)/2+1,r,x,y,x1,y1)%MOD;    return (rowask(2*k,l,(l+r)/2,x,y,(l+r)/2,y1)+rowask(2*k+1,(l+r)/2+1,r,(l+r)/2+1,y,x1,y1))%MOD;}int main(){    int T;    scanf("%d%d",&n,&T);    memset(sum,0,sizeof sum);    while(T--)    {        char op[10];        int x,y,x1,y1;        long long val;        scanf("%s",op);        if(strcmp(op,"Add")==0)        {            scanf("%d%d%lld",&x,&y,&val);            rowadd(1,1,n,x+1,y+1,val);        }        else        {            scanf("%d%d%d%d",&x,&y,&x1,&y1);            printf("%lld\n",(rowask(1,1,n,x+1,y+1,x1+1,y1+1)%MOD+MOD)%MOD);//WA的注意了,输出非负整数,先加上1e9+7再取模        }    }    return 0;}




原创粉丝点击