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;

}

 

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