hdu 1892 See you~

看过这题之后,首先想到的是二维线段树,但是后来做的时候发现不太好搞,因为x和y会相互影响的。

搜了下解题报告,说是用二维树状数组,然后我就自己开始搞。

写过之后虽然AC了,但是跑了1000ms+,感觉太慢了,就搜了下别人的代码,发现我们所理解的二维树状数组有些差别。

我是把每一列当成一个一维的树状数组,等于是n多的一维树状数组,然后这样来看成二维的。

而别人的直接就是用二维来进行查询更新的。

直接看代码吧:

“伪二维树状数组”:

View Code
  1 # include<stdio.h>

  2 # include<string.h>

  3 # define N 1005

  4 int sum[N][N],count[N][N];

  5 int Max(int a,int b)

  6 {

  7     return a>b?a:b;

  8 }

  9 void insert(int i,int j,int num)

 10 {

 11     int t1;

 12     for(t1=j;t1<=1001;t1+=t1&(-t1))

 13         sum[i][t1]+=num;

 14 }

 15 int query(int i,int j)

 16 {

 17     int num=0;

 18     while(j>=1)

 19     {

 20         num+=sum[i][j];

 21         j-=j&(-j);

 22     }

 23     return num;

 24 }

 25 int main()

 26 {

 27     int i,j,ncase,t,n;

 28     int x1,y1,x2,y2,num;

 29     int MAXx,MAXy,MINx,MINy,ans1,ans2,SS;

 30     char word[10];

 31     scanf("%d",&ncase);

 32     for(t=1;t<=ncase;t++)

 33     {

 34         scanf("%d",&n);

 35         memset(sum,0,sizeof(sum));

 36         for(i=1;i<=1001;i++)

 37             for(j=1;j<=1001;j++)

 38             {

 39                 count[i][j]=1;

 40                 insert(i,j,1);

 41             }

 42         printf("Case %d:\n",t);

 43         while(n--)

 44         {

 45             scanf("%s",word);

 46             if(word[0]=='A')

 47             {

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

 49                 x1++;

 50                 y1++;

 51                 count[x1][y1]+=num;

 52                 insert(x1,y1,num);

 53             }

 54             else if(word[0]=='D')

 55             {

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

 57                 x1++;

 58                 y1++;

 59                 if(count[x1][y1]<num) 

 60                 {

 61                     num=count[x1][y1];

 62                     count[x1][y1]=0;

 63                 }

 64                 else count[x1][y1]-=num;

 65                 insert(x1,y1,-num);

 66             }

 67             else if(word[0]=='M')

 68             {

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

 70                 x1++;

 71                 y1++;

 72                 x2++;

 73                 y2++;

 74                 if(count[x1][y1]<num)

 75                 {

 76                     num=count[x1][y1];

 77                     count[x1][y1]=0;

 78                 }

 79                 else count[x1][y1]-=num;

 80                 count[x2][y2]+=num;

 81                 insert(x1,y1,-num);

 82                 insert(x2,y2,num);

 83             }

 84             else

 85             {

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

 87                 x1++;

 88                 y1++;

 89                 x2++;

 90                 y2++;

 91                 MAXx=Max(x1,x2);

 92                 MINx=x1+x2-MAXx;

 93                 MAXy=Max(y1,y2);

 94                 MINy=y1+y2-MAXy;

 95                 SS=0;

 96                 for(i=MINx;i<=MAXx;i++)

 97                 {

 98                     ans1=query(i,MAXy);

 99                     ans2=query(i,MINy-1);

100                     SS+=ans1-ans2;

101                 }

102                 printf("%d\n",SS);

103             }

104         }

105     }

106     return 0;

107 }

二维树状数组:

View Code
View Code 

  1 # include<stdio.h>

  2 # include<string.h>

  3 # define N 1005

  4 int sum[N][N],count[N][N];

  5 int Max(int a,int b)

  6 {

  7     return a>b?a:b;

  8 }

  9 void insert(int i,int j,int num)

 10 {

 11     int t1,t2;

 12     for(t1=i;t1<=1001;t1+=t1&(-t1))

 13         for(t2=j;t2<=1001;t2+=t2&(-t2))

 14             sum[t1][t2]+=num;

 15 }

 16 int query(int i,int j)

 17 {

 18     int num=0,t1,t2;

 19     for(t1=i;t1>0;t1-=t1&(-t1))

 20         for(t2=j;t2>0;t2-=t2&(-t2))

 21             num+=sum[t1][t2];

 22     return num;

 23 }

 24 int main()

 25 {

 26     int i,j,ncase,t,n;

 27     int x1,y1,x2,y2,num;

 28     int MAXx,MAXy,MINx,MINy,ans1,ans2,SS;

 29     char word[10];

 30     scanf("%d",&ncase);

 31     for(t=1;t<=ncase;t++)

 32     {

 33         scanf("%d",&n);

 34         memset(sum,0,sizeof(sum));

 35         for(j=1;j<=1001;j++)

 36             for(i=1;i<=1001;i++)

 37             {

 38                 count[i][j]=1;

 39                 sum[i][j]=(i&(-i))  * (j&(-j));

 40             }

 41         printf("Case %d:\n",t);

 42         while(n--)

 43         {

 44             scanf("%s",word);

 45             if(word[0]=='A')

 46             {

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

 48                 x1++;

 49                 y1++;

 50                 count[x1][y1]+=num;

 51                 insert(x1,y1,num);

 52             }

 53             else if(word[0]=='D')

 54             {

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

 56                 x1++;

 57                 y1++;

 58                 if(count[x1][y1]<num) 

 59                 {

 60                     num=count[x1][y1];

 61                     count[x1][y1]=0;

 62                 }

 63                 else count[x1][y1]-=num;

 64                 insert(x1,y1,-num);

 65             }

 66             else if(word[0]=='M')

 67             {

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

 69                 x1++;

 70                 y1++;

 71                 x2++;

 72                 y2++;

 73                 if(count[x1][y1]<num)

 74                 {

 75                     num=count[x1][y1];

 76                     count[x1][y1]=0;

 77                 }

 78                 else count[x1][y1]-=num;

 79                 count[x2][y2]+=num;

 80                 insert(x1,y1,-num);

 81                 insert(x2,y2,num);

 82             }

 83             else

 84             {

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

 86                 x1++;

 87                 y1++;

 88                 x2++;

 89                 y2++;

 90                 MAXx=Max(x1,x2);

 91                 MINx=x1+x2-MAXx;

 92                 MAXy=Max(y1,y2);

 93                 MINy=y1+y2-MAXy;

 94                 SS=0;

 95                 SS=query(MAXx,MAXy)-query(MAXx,MINy-1)-query(MINx-1,MAXy)+query(MINx-1,MINy-1);

 96                 printf("%d\n",SS);

 97             }

 98         }

 99     }

100     return 0;

101 }

 

 

你可能感兴趣的:(HDU)