upcoj 2174 二维树状数组

简单的树状数组题,从题意可知,由于N太大,直接模拟操作复杂度太高,则利用树状数组的logn算法。

树状数组我只做过一题,然后拿之前的模板来做二维的,没啥难的。

结果abs()里面用了int CE了一次,没注意用了cinTLE了一次,简直傻逼- -。。。

#include<iostream>
#include<cstring>
#include<cmath>
#include<cstdio>
using namespace std;
const int maxt=1025;
int N;
int ar[maxt][maxt];              //数状数组
int c[maxt][maxt];               //模拟图
int lowbit(int t)       //位运算,求最小幂2^k的k
{
    return t&(-t);
}
void add(int j,int t,int v)           //对元素进行加法操作
{
    for(int i=t;i<=maxt;i+=lowbit(i))
    {
        ar[j][i]+=v;
    }
}
int sum(int j,int t)
{
    int s=0;
    for(int i=t;i>0;i-=lowbit(i))
    {
        s+=ar[j][i];
    }
    return s;
}
int sumt(int x,int y)
{
    int sumx=0;
    for(int k=1;k<=x;k++)   //x为数组个数
    {
        sumx+=sum(k,y);         //求和
    }
    return sumx;
}
int main()
{
    memset(ar,0,sizeof(ar));
    memset(c,0,sizeof(c));
    for(int k=1;k<maxt;k++)
        for(int i=1;i<maxt;i++)     //从1开始
        {                               //A为1   //B 为0
            if(k%2==1)                      //k奇数  A为奇数
            {
                if(i%2==1)
                {
                    add(k,i,1);
                    c[k][i]=1;                        //加个模拟
                }
            }
            if(k%2==0)                        //k偶数,A为偶数
            {
                if(i%2==0)
                {
                    add(k,i,1);
                    c[k][i]=1;
                }
            }
        }
        scanf("%d",&N);
        getchar();
        /*for(int i=1;i<=3;i++)
        {
            cout<<endl;
            for(int j=1;j<=3;j++)
            {
                cout<<c[i][j]<<' ';
            }
        }
        cout<<endl;*/
    while(N--)
    {
        //cout<<N<<endl;
        char flag;
       //两种情况 一个是查询

       scanf("%c",&flag);

       if(flag=='R')
       {
            int x1,x2,y1,y2;
            scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
            //cout<<sumt(x2,y2)<<' '<<sumt(x1-1,y1-1)<<' '<<sumt(x1-1,y2)<<' '<<sumt(x2,y1-1)<<endl;
            int tmp1=sumt(x2,y2)+sumt(x1-1,y1-1)-sumt(x1-1,y2)-sumt(x2,y1-1);     // 1的个数
            //int tmp1=abs(sumt(x2,y2)-sumt(x1,y1));
            int tmp2=((y2-y1)+1)*((x2-x1)+1);     //总数
            tmp2=tmp2-tmp1;
            printf("%d %d\n",tmp1,tmp2);
       }
       int tmp;
       if(flag=='A')                       //修改操作
       {
           int x,y;
           tmp=1;
           scanf("%d%d",&x,&y);
           if(c[x][y]!=tmp)
           {
               add(x,y,1);
                c[x][y]=tmp;
           }
       }
       if(flag=='B')
       {
           int x,y;
           tmp=0;
           scanf("%d%d",&x,&y);
           if(c[x][y]!=tmp)
           {
               add(x,y,-1);
                c[x][y]=tmp;
           }
       }
       getchar();
    }
    return 0;
}

原文地址:https://www.cnblogs.com/amourjun/p/5134154.html