1. 程式人生 > >See you~ (hdu1892 二維樹狀陣列)

See you~ (hdu1892 二維樹狀陣列)

Now I am leaving hust acm. In the past two and half years, I learned so many knowledge about Algorithm and Programming, and I met so many good friends. I want to say sorry to Mr, Yin, I must leave now ~~>.<~~. I am very sorry, we could not advanced to the World Finals last year.
When coming into our training room, a lot of books are in my eyes. And every time the books are moving from one place to another one. Now give you the position of the books at the early of the day. And the moving information of the books the day, your work is to tell me how many books are stayed in some rectangles.
To make the problem easier, we divide the room into different grids and a book can only stayed in one grid. The length and the width of the room are less than 1000. I can move one book from one position to another position, take away one book from a position or bring in one book and put it on one position.

Input

In the first line of the input file there is an Integer T(1<=T<=10), which means the number of test cases in the input file. Then N test cases are followed.
For each test case, in the first line there is an Integer Q(1<Q<=100,000), means the queries of the case. Then followed by Q queries.
There are 4 kind of queries, sum, add, delete and move.
For example:
S x1 y1 x2 y2 means you should tell me the total books of the rectangle used (x1,y1)-(x2,y2) as the diagonal, including the two points.
A x1 y1 n1 means I put n1 books on the position (x1,y1)
D x1 y1 n1 means I move away n1 books on the position (x1,y1), if less than n1 books at that position, move away all of them.
M x1 y1 x2 y2 n1 means you move n1 books from (x1,y1) to (x2,y2), if less than n1 books at that position, move away all of them.
Make sure that at first, there is one book on every grid and 0<=x1,y1,x2,y2<=1000,1<=n1<=100.

Output

At the beginning of each case, output "Case X:" where X is the index of the test case, then followed by the "S" queries.
For each "S" query, just print out the total number of books in that area.

Sample Input

2
3
S 1 1 1 1
A 1 1 2
S 1 1 1 1
3
S 1 1 1 1
A 1 1 2
S 1 1 1 2

Sample Output

Case 1:
1
3
Case 2:
1
4

題意:把一個房間劃分成一個矩陣,其中的每個放個都可以放書,且每個方格初始都有一本書,接下來有四種操作:S x1 y1 x2 y2是詢問a[x1][y1]到a[x2][y2]直接有多少本書,A x1 y1 n1意思是向a[x1][y1]中放n1本書,D x1 y1 n1意思是從a[x1][y1]中拿出n1本書,如果不足則全部拿出。M x1 y1 x2 y2 n1意為從a[x1][y1]中拿出n1本書放到a[x2][y2]中,若不足則全部拿出。

這應該是一道比較簡單的二維樹狀陣列的題,詳細請看程式碼:

#include<stdio.h>
#include<string.h>
#include<math.h>
#include<stdlib.h>
#include<algorithm>
using namespace std;
const int N=1005;
int a[N][N],c[N][N];
int lowbit(int i)
{
    return i&(-i);
}
void update(int x,int y,int val)
{
    int i=y;
    while(x<=1001)//這裡最小要開到1001,因為開始時會將x和y++,這裡哇了很久啊!!!
    {
        y=i;
        while(y<=1001)
        {
            c[x][y]+=val;
            y+=lowbit(y);
        }
        x+=lowbit(x);
    }
}
int sum(int x,int y)
{
    int ans=0,i=y;
    while(x>0)
    {
        y=i;
        while(y>0)
        {
            ans+=c[x][y];
            y-=lowbit(y);
        }
        x-=lowbit(x);
    }
    return ans;
}
int main()
{
    char s[2];
    int n,t,k=1,m,x1,x2,y1,y2;
    scanf("%d",&t);
    while(t--)
    {
        memset(a,0,sizeof(a));
        memset(c,0,sizeof(c));
        for(int i=1;i<=1001;i++)//這裡也必須到1001,你懂得
        {
            for(int j=1;j<=1001;j++)
            {
                a[i][j]=1;
                update(i,j,1);
            }
        }
        printf("Case %d:\n",k++);
        scanf("%d",&m);
        for(int i=0;i<m;i++)
        {
            scanf("%s",s);
            if(s[0]=='S')
            {
                scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
                x1++,x2++,y1++,y2++;
                if(x1>x2) swap(x1,x2);
                if(y1>y2) swap(y1,y2);
                //二維求得是一個矩陣的和,劃一下圖就知道為什麼要這樣寫了,用總的減去左邊和右邊不要的,然後再加上多減的一個矩陣
                printf("%d\n",sum(x2,y2)-sum(x2,y1-1)-sum(x1-1,y2)+sum(x1-1,y1-1));
            }
            else if(s[0]=='A')
            {
                scanf("%d%d%d",&x1,&y1,&n);
                x1++,y1++;
                a[x1][y1]+=n;
                update(x1,y1,n);
            }
            else if(s[0]=='D')
            {
                scanf("%d%d%d",&x1,&y1,&n);
                x1++,y1++;
                if(a[x1][y1]<n) n=a[x1][y1];
                update(x1,y1,-n);
                a[x1][y1]-=n;//
            }
            else
            {
                scanf("%d%d%d%d%d",&x1,&y1,&x2,&y2,&n);
                x1++,y1++,x2++,y2++;
                if(a[x1][y1]<n) n=a[x1][y1];
                update(x1,y1,-n);
                update(x2,y2,n);
                a[x1][y1]-=n;//
                a[x2][y2]+=n;//
            }
        }
    }
}

相關推薦

See you~ hdu1892 陣列

Now I am leaving hust acm. In the past two and half years, I learned so many knowledge about Algorithm and Programming, and I met so many

poj2155 Matrix經典陣列

吐槽:這題先說[x1,y1]和[x2,y2]是左上角和右下角的兩個點,又說x1<=x2&&y1<=y2,那就是x軸向右,y軸向下為正方向。mdzz啊,座標系這種東西能不能

codeforces869EThe Untended Antiquity陣列

/* 二維樹狀陣列+Hash 題意: 給一個地圖(n,m) 三種操作: 1,在以(r1,c1)、(r2,c2)為對角的矩形四條邊上新增障礙 2,消除以(r1,c1)、(r2,c2)為對角的矩形四條邊上的障礙 3,判斷(r1,c1)到(r2,c2)是否存在一條路徑,不經過障礙 利用二維樹

2015年ACM/ICPC瀋陽賽區 I題陣列

題意:給你n(n<=1e5)個正整數二元組<a,b> (1<=a,b<=1e5) 給你m(m<=1e5)個正整數三元組<c,d,e>(1<=c,d<=1e3  1<=e<=1e5) 定義新

2018.10.23【校內模擬】行星通道計劃陣列

傳送門 解析: 我們發現,每一條線段會把原來的環狀分成兩段,兩條線段有交點當且僅當一條線段的起終點分別在另一條線段把環形分成的兩個部分中。 所以直接斷環成鏈,每次新加線段&lt;u,v&gt;&lt;u,v&gt;<u,v

NOIP模擬 行星通道計劃陣列

QAQ 【題目分析】 考慮樹狀陣列維護狀態,然後。。。。。就沒有然後了。。。。。沒想出來二維如何統計。 感覺正解很毒瘤啊,各種壓位操作。。。。所以正常打個二維樹狀陣列還是能過啊。。。。 考慮兩個連線點x,y,如果以後有兩個點x',y'經過他,那麼一定滿足x<x'

【CF869E】The Untended Antiquity雜湊+陣列

當覆蓋兩點的最小矩形不同時,一定不可達 這樣的問題不難想到經典的二維樹狀陣列+差分來支援二維區間覆蓋+查詢 對於覆蓋操作 我們可以差分的給這個矩陣里加上一個編號 對於操牆操作 我們可以反著減去這個編號 對於查詢 就查詢這兩個點的值是否相同 編號的累積不影響 因為只有在同一個牆內才會累積 注意 如果只是單單的把

POJ2155 - Matrix 陣列

                                          &nb

codeforces DIV2 E. Garlands 離線、陣列

題意: 給出你一個n*m矩陣,矩陣中有一些燈泡,這些燈泡連成了k條互不重疊的鏈。每個燈泡都有一定的權值w,但是隻有當燈泡開啟的時候,才會產生貢獻,剛開始所有的燈泡都是開著的。共有q次詢問,有兩種操作: ①“Switch i”——表示將編號為i的

poj 2155 Matrix陣列

樓教主出的二維樹狀陣列。 給出矩陣左上角和右下角座標,矩陣裡的元素 1變0 ,0 變1,然後給出詢問,問某個點是多少。 糾結好久了,一直沒什麼好思路,看discuss說四個角神馬的,我搜了下,理解了,樹狀數組裡記錄該點的變幻次數,或者直接%2也行。 查詢的時候Gets

POJ-2155陣列

學習了這篇部落格的講解徹底弄懂二維樹狀陣列,做了二維樹狀陣列的第1題。 雖然是二維,但跟一維的思想基本相同,只不過一維時用C[i]表示a[i-lowbit[i]+1] ~ a[i]的和,二維時用c[i][j]表示a[i-lowbit[i]+1][j-lowbit[j]+1

hdu 5517 三元組陣列

思路: 第一眼看還覺得沒法處理,但是我們可以發現他要求top三元組,所以對於二元組  a b 對於每個b 我只需要保留他的最大的a就可以了。生成的新的三元組最多就100000 個。 這樣的話,就直接  二維樹狀陣列求就可以了。 程式碼: #include<bit

陣列模板單點更新,區間求和以HDU 2642為例

題目:點選開啟連結 題意:輸入B後輸入座標,表示對應的點的燈變亮,輸入D後輸入座標表示對應的點燈滅,輸入Q後輸入一個矩形的左下角和右上角 輸出矩形內亮著的等的個數,注意燈亮過不能再亮,燈關了不能再關,所以用陣列標記,樹狀陣列模板中元素下標均從1開始,題目從0開始所以加1。

POJ1195:Mobile phones 陣列 矩陣上點的區間和查詢更新均為

Description Suppose that the fourth generation mobile phone base stations in the Tampere area operate as follows. The area is divided int

牛客網暑期ACM多校訓練營第二場J.farm (隨機數+陣列)

題目連結 時間限制:C/C++ 4秒,其他語言8秒 空間限制:C/C++ 262144K,其他語言524288K 64bit IO Format: %lld 題目描述 White Rabbit has a rectangular farmland of n*m. In

POJ 2155 Matrix陣列+陣列陣列區間更新+單點查詢

Given an N*N matrix A, whose elements are either 0 or 1. A[i, j] means the number in the i-th row and j-th column. Initially we have A[

陣列區間修改,單點查詢

好像不管是幾維都和一維原理差不多,多了一個維度也就多了一層迴圈而已(QAQ) #include <cstdio> #include <cstdlib> #include <cstring> #include <cmath&g

HDU 5517 三偏序 陣列

題意:已知A集合(a,b),B集合(c,d,e)C=A*B=(a, c, d)在b和e相等的情況下才可以,問題是求出C中有幾個元素,該元素除了自己沒有比他大的,'>'的定義是當 a>=a' && b>=b' && c>=c'時,才成立。

Matrix POJ - 2155 (陣列)

題意:      給定一個初始化全為0的01矩陣.有兩種操作: C: x1,y1,x2,y2 翻轉矩形內的01 Q  x,y 查詢座標為x,y是啥 分析:       以前寫過一維的用樹狀陣列區間更新的題.

Triple HDU - 5517 —— 陣列

Given the finite multi-set A of n pairs of integers, an another finite multi-set B of m triples of integers, we define the product of A and B as a