BZOJ2683 简单题 题解&代码

来源:互联网 发布:软件销售ppt 编辑:程序博客网 时间:2024/06/05 00:42

题意:
给出n*n的棋盘,初始值为0,维护两种操作:
1 x y a 给(x,y)处加a
2 x1 y1 x2 y2 查询(x1,y1)(x2,y2)的矩形内部的和
对每次求和都需要输出答案

思路:
其实我是直接看题解是cdq分治的【捂脸】不敢随意装逼,只是写了一次cdq分治熟悉了一下
插入和查询都是单点操作(查询操作可以修改为4个单点的二维前缀和)
不知所云…有点尴尬,我思考一下再说orz

/**************************************************************    Problem: 2683    User: Rainbow6174    Language: C++    Result: Accepted    Time:8064 ms    Memory:27060 kb****************************************************************/#include<iostream>#include<algorithm>#include<cstdio>using namespace std;const int maxc = 200005;int n,c,tot,cnt,x1,y1,x2,y2,a[maxc*4],p[maxc*4],x[maxc*4],y[maxc*4],z[maxc*4],op[maxc*4],ans[maxc],id[maxc*4],ls[maxc*4];bool cmp(int idx,int idy){    if(x[idx]==x[idy])        if(y[idx]==y[idy])return z[idx]<z[idy];        else return y[idx]<y[idy];    return x[idx]<x[idy];}int lowbit(int x){    return x&(-x);}void insert(int x,int l){    for(int i = x; i < maxc*4; i+=lowbit(i))        a[i]+=l;}int getsum(int x){    int ret = 0;    for(int i = x; i > 0; i-=lowbit(i))        ret+=a[i];    return ret;}void cdq(int l,int r){    if(l==r)return;    //cout<<l<<' '<<r<<endl;    int mid=(l+r)/2;    for(int i = l; i <= r; i++)    if(z[p[i]]==1){        if(p[i]<=mid) insert(y[p[i]],op[p[i]]);    }    else if(p[i]>mid){        ans[id[p[i]]] += op[p[i]]*getsum(y[p[i]]);    }    for(int i = l; i <= r; i++)        if(z[p[i]]==1 && p[i]<=mid) insert(y[p[i]],-op[p[i]]);    int l1=l,l2=mid+1;    for(int i = l; i <= r; i++)        if(p[i]<=mid) ls[l1++] = p[i];        else ls[l2++] = p[i];    for(int i = l; i <= r; i++) p[i] = ls[i];    cdq(l,mid);    cdq(mid+1,r);}int main(void){    scanf("%d",&n);    while(scanf("%d",&c) && c!=3)    {        p[++tot]=tot;z[tot]=c;        if(c==1)scanf("%d%d%d",&x[tot],&y[tot],&op[tot]);        else        {            scanf("%d%d%d%d",&x1,&y1,&x2,&y2);            x[tot]=x1-1;y[tot]=y1-1;op[tot]=1;id[tot]=++cnt;            p[++tot]=tot;z[tot]=c;            x[tot]=x1-1;y[tot]=y2;op[tot]=-1;id[tot]=cnt;            p[++tot]=tot;z[tot]=c;            x[tot]=x2;y[tot]=y1-1;op[tot]=-1;id[tot]=cnt;            p[++tot]=tot;z[tot]=c;            x[tot]=x2;y[tot]=y2;op[tot]=1;id[tot]=cnt;        }    }    sort(p+1,p+1+tot,cmp);    //for(int i = 1; i <= tot; i++)        //cout<<p[i]<<' '<<id[p[i]]<<' '<<z[p[i]]<<' '<<op[p[i]]<<' '<<x[p[i]]<<' '<<y[p[i]]<<' '<<getsum(y[i])<<endl;    cdq(1,tot);    for(int i = 1; i <= cnt; i++)printf("%d\n",ans[i]);    return 0;}
0 0
原创粉丝点击