bzoj1452

二维树状数组or树套树

树套树在bzoj上T了,在洛谷上AC了(卡着1000ms的上限跑的,交了n发才过)

二维树状数组跑的飞快

二维树状数组代码:

/**************************************************************

    Problem: 1452

    User: syh0313

    Language: C++

    Result: Accepted

    Time:4672 ms

    Memory:42960 kb

****************************************************************/

 

#include <iostream>

#include <cstdio>

#include <cstdlib>

#include <cstring>

#include <string>

#include <cmath>

using namespace std;

const int maxn=310;

int n,m,q,col[maxn][maxn],a[110][maxn][maxn];

int lowbit(int x){return x&(-x);}

void add(int k,int x,int y,int kk)

{

    while (x<=n)

    {

        for (int i=y;i<=m;i+=lowbit(i)) a[k][x][i]+=kk;

        x+=lowbit(x);

    }

}

int qury(int kk,int x,int y)

{

    int sum=0;

    while (x)

    {

        for (int i=y;i;i-=lowbit(i)) sum+=a[kk][x][i];

        x-=lowbit(x);

    }

return sum;

}

int main()

{

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

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

     for  (int j=1;j<=m;j++)

     {

        scanf("%d",&col[i][j]);

        add(col[i][j],i,j,1);

     }

    scanf("%d",&q);

    while (q--)

    {

        int ff; scanf("%d",&ff);

        if (ff==1)

        {

            int xx,yy,kk; scanf("%d%d%d",&xx,&yy,&kk);

            add(col[xx][yy],xx,yy,-1);

            add(kk,xx,yy,1); col[xx][yy]=kk;

        }

        else

        {

            int x,xx,y,yy,kk; scanf("%d%d%d%d%d",&x,&xx,&y,&yy,&kk);

            printf("%d\n",qury(kk,xx,yy)-qury(kk,x-1,yy)-qury(kk,xx,y-1)+qury(kk,x-1,y-1));

        }

    }

return 0;

}

树套树洛谷AC代码:

/**************************************************************

    Problem: 1452

    User: syh0313

    Language: C++

    Result: Time_Limit_Exceed

****************************************************************/

 

#include <iostream>

#include <cstdio>

#include <cstdlib>

#include <cstring>

#include <string>

#define lch a[n].lc

#define rch a[n].rc

using namespace std;

const int maxn=310;

struct da{int lc,rc,sum;}a[100000*maxn];

struct daa{int lc,rc,sum;}b[10000*maxn];

int n,m,col[1100],root[10000*maxn],topt,cnt,q,co[maxn][maxn];

inline void updata(int n){a[n].sum=a[lch].sum+a[rch].sum;}

inline void tree_add_2(int &n,int l,int r,int lc,int k)

{

    if (!n) n=++cnt;

    if (l==r) {a[n].sum+=k; return;}

    int mid=(l+r)>>1;

    if (lc<=mid) tree_add_2(lch,l,mid,lc,k);

     else tree_add_2(rch,mid+1,r,lc,k);

    updata(n);

}

inline void tree_add(int &n,int l,int r,int lx,int ly,int k)

{

    if (!n) n=++topt;

    tree_add_2(root[n],1,m,ly,k);

    if (l==r) return;

    int mid=(l+r)>>1;

    if (lx<=mid) tree_add(b[n].lc,l,mid,lx,ly,k);

     else tree_add(b[n].rc,mid+1,r,lx,ly,k);

}

inline int qury_2(int &n,int L,int R,int l,int r)

{

    if (!n) return 0;

    if (L==l && R==r) return a[n].sum;

    int mid=(L+R)>>1;

    if (r<=mid) return qury_2(lch,L,mid,l,r);

     else if (l>=mid+1) return qury_2(rch,mid+1,R,l,r);

return qury_2(lch,L,mid,l,mid)+qury_2(rch,mid+1,R,mid+1,r);

}

inline int qury(int n,int L,int R,int l,int r,int y1,int y2)

{

    if (!n) return 0;

    if (L==l && R==r) return qury_2(root[n],1,m,y1,y2);

    int mid=(L+R)>>1;

    if (r<=mid) return qury(b[n].lc,L,mid,l,r,y1,y2);

     else if (l>=mid+1) return qury(b[n].rc,mid+1,R,l,r,y1,y2);

return qury(b[n].lc,L,mid,l,mid,y1,y2)+qury(b[n].rc,mid+1,R,mid+1,r,y1,y2);

}

inline char nc(void)

{

    static char ch[100010],*p1=ch,*p2=ch;

    return p1==p2&&(p2=(p1=ch)+fread(ch,1,100010,stdin),p1==p2)?EOF:*p1++;

}

inline int read()

{

    int xxx=0,ff=1; char c=nc();

    while (c<'0' || c>'9') {if (c=='-') ff=-1; c=nc();}

    while (c>='0' && c<='9') {xxx=(xxx<<1)+(xxx<<3)+c-'0'; c=nc();}

return xxx*ff;

}

int main()

{

    n=read(); m=read(); register int i,j;

    for (i=1;i<=n;i++)

     for (j=1;j<=m;j++)

     {

        int xx; xx=read(); co[i][j]=xx;

        tree_add(col[xx],1,n,i,j,1);

     }

    q=read();

    while (q--)

    {

        int ff; ff=read();

        if (ff==1)

        {

            int xx,yy,kk; xx=read(); yy=read(); kk=read();

            tree_add(col[co[xx][yy]],1,n,xx,yy,-1);

            tree_add(col[kk],1,n,xx,yy,1); co[xx][yy]=kk;

        }

        else

        {

            int x,y,xx,yy,kk;

            x=read(); xx=read(); y=read(); yy=read(); kk=read();

            printf("%d\n",qury(col[kk],1,n,x,xx,y,yy));

        }

    }

return 0;

}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值