Hdu 1892 step5.3.1 See you~(樹狀數組)

Hdu 1892 step5.3.1 See you~

 

Time Limit: 5000/3000 MS (Java/Others)Memory Limit: 65535/32768 K (Java/Others)

Total Submission(s): 175 AcceptedSubmission(s): 56

 

Problem Description

Now I am leaving hust acm. In the past twoand 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 leavenow ~~>.<~~. I am very sorry, we could not advanced to the World Finalslast year.

When coming into our training room, a lotof books are in my eyes. And every time the books are moving from one place toanother 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 howmany books are stayed in some rectangles.

To make the problem easier, we divide theroom into different grids and a book can only stayed in one grid. The lengthand the width of the room are less than 1000. I can move one book from oneposition to another position, take away one book from a position or bring inone book and put it on one position.

 

 

Input

In the first line of the input file thereis an Integer T(1<=T<=10), which means the number of test cases in theinput file. Then N test cases are followed.

For each test case, in the first line thereis an Integer Q(1<Q<=100,000), means the queries of the case. Thenfollowed 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 thetotal books of the rectangle used (x1,y1)-(x2,y2) as the diagonal, includingthe two points.

A x1 y1 n1 means I put n1 books on theposition (x1,y1)

D x1 y1 n1 means I move away n1 books onthe position (x1,y1), if less than n1 books at that position, move away all ofthem.

M x1 y1 x2 y2 n1 means you move n1 booksfrom (x1,y1) to (x2,y2), if less than n1 books at that position, move away allof them.

Make sure that at first, there is one bookon 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 printout 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

 

 

Author

Sempr|CrazyBird|hust07p43

 

 

Source

HDU 2008-4 Programming Contest

題解:

第一次寫線段數組的題,這道題是一個二維的樹狀數組,比較特殊的是,裏面每一個點都只有一本書,所以可以直接算出每一行的線段數組。因爲沒有記錄每一個位置的書數,所以減去書本和加上書本是函數是不一樣的,在減去某一位置的書本時,要先算出同一行到該位置的書本數,和前一個位置的書本數,相減才能算出當前位置的書本數。在減去書本和移動書本時,還要判斷該位置的書是否足夠要減去的數量,如果不夠就全部書本都減掉。

源代碼:

#include <iostream>

#include <string>

#include <math.h>

#include <algorithm>

#define MAX 1005

using namespace std;

 

int rec[MAX][MAX],temp[MAX][MAX];

int mult[11];

 

int lowbit(int x)

{

   returnx&(-x);

}

 

int Mod(int n)

{

   for(int i = 2;i <= 10;i++)

   {

     if(n% mult[i] == mult[i-1])

        returnmult[i-1];

   }

   return0;

}

 

void getrec()

   for(int k = 1;k < MAX;k++)

   {

     if(k%2)

        temp[1][k] = 1;

     else

        temp[1][k] = Mod(k);

   }

   for(int i = 2;i < MAX;i++)

   {

     for(int k = 1;k < MAX;k++)

        temp[i][k] = temp[1][k];

   }

}

 

int getsum(int x,int y)

{

   intsum = 0;

   while(y> 0)

   {

     sum += rec[x][y];

     y -= lowbit(y);

   }

   returnsum;

}

void init()

{

   for(int i = 0;i < MAX;i++)

     for(int k = 0;k < MAX;k++)

        rec[i][k] = temp[i][k];

}

 

void add(int x,int y,int num)

{

   while(y> 0 && y < MAX)

   {

     rec[x][y] += num;

     y += lowbit(y);

   }

}

 

void dec(int x,int y,int num)

{

   if(y% 2)

   {

     if(rec[x][y]< num)

        num = rec[x][y];

   }

   else

   {

     intsum = getsum(x,y) - getsum(x,y-1);

     if(sum< num)

        num = sum;

   }

 

   while(y> 0 && y < MAX)

   {

     rec[x][y] = rec[x][y] - num;

     y += lowbit(y);

   }

 

}

 

 

void move(int x,int y,int x1,int y1,int num)

{

   if(y% 2)

   {

     if(num> rec[x][y])

        num = rec[x][y];

   }

   else

   {

     intsum = getsum(x,y) - getsum(x,y-1);

     if(sum< num)

        num = sum;

   }

   dec(x,y,num);

   add(x1,y1,num);

}

 

void Swap(int &x,int &y)

{

   intt = x;

   if(x> y)

   {

     x = y;

     y = t;

   }

}

 

int main()

{

   for(int i = 1; i <= 10;i++)

     mult[i] = pow(2.0,i);

   getrec();

 

   intn;

   cin >> n;

   charstr[5];

   intx1,x2,y1,y2,num;

 

   for(int i = 0;i < n;i++)

   {

     init();

     intm;

     cin >> m;

     cout << "Case "<<i+1<<":" << endl;

     for(int k = 0;k < m;k++)

     {

        scanf("%s",str);

        if(str[0]== 'S')

        {

          scanf("%d%d%d%d",&x1,&y1,&x2,&y2);

          Swap(x1,x2);

          Swap(y1,y2);

          intsum = 0;

          y2 += 1;

          for(int j = x1+1;j <= x2+1;j++)

          {

             if(y1)

               sum += getsum(j,y2) -getsum(j,y1);

             else

               sum += getsum(j,y2);

          }

          cout << sum <<endl;

        }

        elseif(str[0] == 'A')

        {

          scanf("%d%d%d",&x1,&y1,&num);

          add(x1+1,y1+1,num);

        }

        elseif(str[0] == 'D')

        {

          scanf("%d%d%d",&x1,&y1,&num);

          dec(x1+1,y1+1,num);

        }

        elseif(str[0] == 'M')

        {

          scanf("%d%d%d%d%d",&x1,&y1,&x2,&y2,&num);

          move(x1+1,y1+1,x2+1,y2+1,num);

        }

     }

   }

   return0;

}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章