【】 BZOJ1176 Bugs

Title effect: given a rectangular N * N, Q has operations, each operation may be rectangular modify or query a single point weights and sub-rectangle.

Problem solution: CDQ partition suited to handle independently of each other modifications between operating and support topics offline.
Meet the above operating conditions can obviously do the tree tree cover, but the amount of code to take off, I could not write qaq. .
We learned cdq use divide and conquer to solve this problem. It found that there is a time dimension between operations, namely: the ability to generate contributions to the current query operations must be time to modify operations before the inquiry. Weight maintenance sub-rectangle and a two-dimensional prefix and can be treated, namely: Maintenance (1,1) and the weights can be between (n, m). Thus, it transformed into the problem at a given time dimension premise, seeking to satisfy x1 <x2 and y1 <y2 all (x1, y1) of the point corresponding to the point and right, namely: a three-dimensional partial order problem.

code show as below

#include <cstdio>
using namespace std;
const int maxn=2e6+10;
const int maxq=2e5+10;

int n,s,bit[maxn],ans[maxq];
struct node{int x,y,val,opt,aid;}q[maxq],tmp[maxq];// opt: 0 -> modify 1 -> query
int cnt,tot;
void modify(int pos,int val){
    for(int i=pos;i<=n;i+=i&-i)bit[i]+=val;
}
int query(int pos){
    int ret=0;
    for(int i=pos;i;i-=i&-i)ret+=bit[i];
    return ret;
}

void cdq(int l,int r){
    if(l==r)return;
    int mid=l+r>>1;
    cdq(l,mid),cdq(mid+1,r);
    int x=l,y=mid+1;
    for(int i=l;i<=r;i++){
        if(y>r||(x<=mid&&q[x].x<=q[y].x)){
            tmp[i]=q[x];
            if(q[x].opt==0)modify(q[x].y,q[x].val);
            ++x;
        }else{
            tmp[i]=q[y];
            if(q[y].opt==1)ans[q[y].aid]+=query(q[y].y)*q[y].val;
            ++y;
        }
    }
    for(int i=l;i<=mid;i++)if(q[i].opt==0)modify(q[i].y,-q[i].val);
    for(int i=l;i<=r;i++)q[i]=tmp[i];
}
void add(int x,int y,int val,int opt){
    ++tot,q[tot].x=x,q[tot].y=y,q[tot].val=val,q[tot].opt=opt;
    if(q[tot].opt==1)q[tot].aid=cnt;
}
void read_and_parse(){
    scanf("%d%d",&s,&n);
    while(1){
        int opt;scanf("%d",&opt);
        if(opt==3)break;
        if(opt==1){
            int x,y,a;
            scanf("%d%d%d",&x,&y,&a);
            add(x,y,a,0);
        }
        if(opt==2){
            int x1,x2,y1,y2;
            scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
            ++cnt,add(x2,y2,1,1),add(x2,y1-1,-1,1),add(x1-1,y2,-1,1),add(x1-1,y1-1,1,1);
        }
    }
}
void solve(){
    cdq(1,tot);
    for(int i=1;i<=cnt;i++)printf("%d\n",ans[i]);
}
int main(){
    read_and_parse();
    solve();
    return 0;
} 

Guess you like

Origin www.cnblogs.com/wzj-xhjbk/p/11109649.html