hdu1892 (summer III see you)

来源:互联网 发布:手机网络劫持怎么办 编辑:程序博客网 时间:2024/05/29 15:35

本题也属于比较简单的二维树状数组问题。

思路很简单:单点向上记录,向下求和,不过一直AC不了,总结一下每次出现错误的原因:

1、一开始mle。。。后来查了一下,是因为数组开得太大,看来数组还是要看情况来开,根据情况,适合就好。

2、然后就是各种WA。。。对比AC代码后发现,是因为一下两个原因:a、对于单点书本的判断的表达式书写出错。(应该和区域的计算表达式差不多) b、除了add外其他的update函数在更新时坐标都不需要+1,因为add的时候,已经从(1,1)开始取,所以后面的其他操作也就不用+1。

3、当我以为这些问题都解决,可以AC时,OJ抛出了了个TLE。。。检查了好多遍感觉都不会T啊,可是事实就是如此残忍。。。在我把主算法一个个换走后发现,原来是if-else太多引起的问题。原来if-else 也会增加复杂度。以后应该要对题目给出的数据敏感一点,如<=10,就是为了让我用for循环进行初始化c数组为1。,


先附上AC代码(此为转载的代码,因为自己后来修改的版本已经几乎接近这个了,所以直接上这个):

#include <cstdio>#include <cstring>#include <iostream>using namespace std;const int size = 1010;int a[size+1][size+1];int lowbit(int i){    return i & (-i);}void add(int x, int y, int num){    for(int i = x; i <= size; i += lowbit(i))        for(int j = y; j <= size; j += lowbit(j))            a[i][j] += num;}int getSum(int x, int y){    int tot = 0;    for(int i = x; i > 0; i -= lowbit(i))        for(int j = y; j > 0; j -= lowbit(j))            tot += a[i][j];    return tot;}void init(){    memset(a, 0, sizeof(a));    for(int i = 1; i < size; ++i)        for(int j = 1; j < size; ++j)            add(i, j, 1);}int main(){    int T, n, x1, x2, y1, y2, n1;    char cmd[3];    scanf("%d", &T);    for(int cnt = 1; cnt <= T; ++cnt)    {        init();        scanf("%d", &n);        printf("Case %d:\n", cnt);        while(n--)        {            scanf("%s", cmd);            if(cmd[0] == 'A')            {                scanf("%d%d%d", &x1, &y1, &n1);                add(x1+1, y1+1, n1);            }            else if(cmd[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);                int temp;                temp=getSum(x2,y2)-getSum(x1-1,y2)-getSum(x2,y1-1)+getSum(x1-1,y1-1);                printf("%d\n",temp);            }            else if(cmd[0] == 'D')            {                scanf("%d%d%d",&x1,&y1,&n1);                ++x1;                ++y1;                int temp;                temp=getSum(x1,y1)-getSum(x1-1,y1)-getSum(x1,y1-1)+getSum(x1-1,y1-1);                if(n1 > temp)                    n1 = temp;                add(x1, y1, -n1);            }            else if(cmd[0] == 'M')            {                scanf("%d%d%d%d%d", &x1, &y1, &x2, &y2, &n1);                ++x1;                ++x2;                ++y1;                ++y2;                int temp;                temp=getSum(x1,y1)-getSum(x1-1,y1)-getSum(x1,y1-1)+getSum(x1-1,y1-1);                if(n1 > temp)                    n1 = temp;                add(x1, y1, -n1);                add(x2, y2, n1);            }        }    }    return 0;}

TLE:

#include<cstdio>#include<cstring>#include<cmath>#include<algorithm>#include<cmath>using namespace std;const int maxn=1011;int c[maxn+1][maxn+1],n,casenum,cases=0,queries;char str[10];int lowbit(int x){    return x&(-x);}void update(int i,int j,int val){   for(int x=i;x<maxn;x+=lowbit(x))    for(int y=j;y<maxn;y+=lowbit(y))   {       c[x][y]+=val;   }}int getsum(int i,int j){   int result=0;   for(int x=i;x>0;x-=lowbit(x))   {       for(int y=j;y>0;y-=lowbit(y)){        result+=c[x][y];       }   }   return result;}void init(){           memset(c,0,sizeof(c));           for(int i=1;i<maxn;i++)            for(int j=1;j<maxn;j++)            update(i,j,1);}int main(){    scanf("%d",&casenum);    while(casenum--)    {        cases++;        printf("Case %d:\n",cases);        init();        scanf("%d%*c",&queries);        for(int i=1;i<=queries;i++)        {            scanf("%s",str);            if(str[0]=='S')            {                int x1,x2,y1,y2,n1,n2,m1,m2,sum;                scanf("%d%d%d%d",&x1,&y1,&x2,&y2);                n1=max(x1,x2);                n2=min(x1,x2);                m1=max(y1,y2);                m2=min(y1,y2);                sum=getsum(n1+1,m1+1)-getsum(n2,m1+1)-getsum(n1+1,m2)+getsum(n2,m2);                printf("%d\n",sum);            }            if(str[0]=='A')            {                int xx,yy,nn;                scanf("%d%d%d",&xx,&yy,&nn);                update(xx+1,yy+1,nn);            }            if(str[0]=='D')            {                int xxx,yyy,nnn,t;                scanf("%d%d%d",&xxx,&yyy,&nnn);                t=getsum(xxx,yyy)-getsum(xxx,yyy+1)-getsum(xxx+1,yyy)+getsum(xxx,yyy);                if(t<=nnn)                    update(xxx,yyy,-t);                    else                        update(xxx,yyy,-nnn);            }            if(str[0]=='M')            {                int xx1,xx2,yy1,yy2,tt,nnnn;                scanf("%d%d%d%d%d",&xx1,&yy1,&xx2,&yy2,&nnnn);                tt=getsum(xx1+1,yy1+1)-getsum(xx1,yy1+1)-getsum(xx1+1,yy1)+getsum(xx1,yy1);                if(nnnn>=tt)                {                    update(xx1,yy1,-tt);                    update(xx2,yy2,tt);                }                else                {                    update(xx1,yy1,-nnnn);                    update(xx2,yy2,nnnn);                }            }        }    }    return 0;}


原创粉丝点击