树状数组(Garlands,codeforces 707e)

来源:互联网 发布:php语言精粹 编辑:程序博客网 时间:2024/06/16 11:02

看了别人的代码写的。

不是官方解法。

所以速度比较慢。

把STL和结构体都去掉后才勉强过。

而且还钻了题目的空子。

在多达10^5个询问中,ASK却不会超过2000个。

因此这种解法才可行。

否则空间都开不下。

但比官方解法编程难度低。

离线算法。

用了二维树状数组。


#include<stdio.h>#define maxn 2010#define maxq 1000010typedef long long ll;int n,m,k,q,cnt;ll tree[maxn][maxn];ll ans[maxn][maxn];int x[maxn][maxn];int y[maxn][maxn];int w[maxn][maxn];int l[maxn];bool st[maxn];char ch[maxq];int bh[maxq];int x1[maxn];int y1[maxn];int x2[maxn];int y2[maxn];int id[maxq];void add(int x,int y,int val){    for(int i=x;i<=n;i+=i&(-i))        for(int j=y;j<=m;j+=j&(-j))            tree[i][j]+=val;}ll qry(int x,int y){    ll ret=0;    for(int i=x;i;i-=i&(-i))        for(int j=y;j;j-=j&(-j))            ret+=tree[i][j];    return ret;}int main(){    scanf("%d %d %d",&n,&m,&k);    for(int i=1;i<=k;i++)    {        scanf("%d",&l[i]);        for(int j=1;j<=l[i];j++)            scanf("%d %d %d",&x[i][j],&y[i][j],&w[i][j]);    }    char str[100];    scanf("%d",&q);    for(int i=1;i<=q;i++)    {        scanf("%s",str);        ch[i]=str[0];        if(ch[i]=='A')        {            id[i]=++cnt;            scanf("%d %d %d %d",&x1[cnt],&y1[cnt],&x2[cnt],&y2[cnt]);        }        else scanf("%d",&bh[i]);    }    for(int i=1;i<=k;i++)    {        for(int j=1;j<=l[i];j++) add(x[i][j],y[i][j],w[i][j]);        for(int j=1;j<=cnt;j++) ans[i][j]=qry(x2[j],y2[j])-qry(x1[j]-1,y2[j])-qry(x2[j],y1[j]-1)+qry(x1[j]-1,y1[j]-1);        for(int j=1;j<=l[i];j++) add(x[i][j],y[i][j],-w[i][j]);    }    for(int i=1;i<=q;i++)    {        if(ch[i]=='A')        {            ll ANS=0;            for(int j=1;j<=k;j++)                if(!st[j])                    ANS+=ans[j][id[i]];            printf("%I64d\n",ANS);        }        else st[bh[i]]^=1;    }    return 0;}


0 0
原创粉丝点击