P4390 [BOI2007]Mokia 摩基亚(cdq分治)

一样是cdq的板子

照着园丁的烦恼就好了

代码

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
int w,cntq,cnta,nothing,type,qid,aid;
namespace BIT{
    int bit[2000100];
    int lowbit(int x){
        return x&(-x);
    }
    void add(int pos,int x){
        while(pos<=w){
            bit[pos]+=x;
            pos+=lowbit(pos);
        }
    }
    int query(int pos){
        int ans=0;
        while(pos){
            ans+=bit[pos];
            pos-=lowbit(pos);
        }
        return ans;
    }
    void clear(int pos){
        while(pos<=w){
            if(bit[pos])
                bit[pos]=0;
            else   
                break;
            pos+=lowbit(pos);
        }
    }
};

int ans[10100];
struct Query{
    int type,val,posx,posy,IorD,aid;
    bool operator < (const Query &b) const{
        return posx==b.posx?type<b.type:posx<b.posx;
    }
}query[200100];
Query tmp[200100];
void cdq(int L,int R){
    // printf("%d %d",L,R);
    if(R<=L+1)
        return;
    int mid=(L+R)>>1;
    cdq(L,mid);
    cdq(mid,R);
    int l=L,r=mid,tot=0;
    while(l<mid&&r<R){
        if(query[l]<query[r]){
            if(query[l].type==1)
                BIT::add(query[l].posy,query[l].val);
            tmp[++tot]=query[l++];
        }
        else{
            if(query[r].type==2)
                ans[query[r].aid]+=query[r].IorD*BIT::query(query[r].posy);
            tmp[++tot]=query[r++];
        }
    }
    while(l<mid)
        tmp[++tot]=query[l++];
    while(r<R){
        if(query[r].type==2)
            ans[query[r].aid]+=query[r].IorD*BIT::query(query[r].posy);
        tmp[++tot]=query[r++];
    }
    for(int i=1;i<=tot;i++){
        BIT::clear(tmp[i].posy);    
        query[L+i-1]=tmp[i];
    }
}
int main(){ 
    scanf("%d %d",&nothing,&w);
    scanf("%d",&type);
    w++;
    while(type!=3){
        if(type==1){
            int x,y,a;
            scanf("%d %d %d",&x,&y,&a);
            // x+=2;y+=2;
            x++,y++;

            query[++qid].type=1;
            query[qid].posy=y; 
            query[qid].posx=x;
            query[qid].val=a;
        }
        else{
            int x1,y1,x2,y2;
            scanf("%d %d %d %d",&x1,&y1,&x2,&y2);
            // x1+=2,x2+=2,y1+=2,y2+=2;
            x1++,x2++,y1++,y2++;

            query[++qid].type=2;
            query[qid].aid=++aid;
            query[qid].IorD=1;
            query[qid].posx=x2;
            query[qid].posy=y2;
        
            query[++qid].type=2;
            query[qid].aid=aid;
            query[qid].IorD=-1;
            query[qid].posx=x1-1;
            query[qid].posy=y2;

            query[++qid].type=2;
            query[qid].aid=aid;
            query[qid].IorD=-1;
            query[qid].posx=x2;
            query[qid].posy=y1-1;

            query[++qid].type=2;
            query[qid].aid=aid;
            query[qid].IorD=1;
            query[qid].posx=x1-1;
            query[qid].posy=y1-1;
        }
        scanf("%d",&type);
    }
    cdq(0,qid+1);
    for(int i=1;i<=aid;i++)
        printf("%d
",ans[i]);
    return 0;
}
原文地址:https://www.cnblogs.com/dreagonm/p/10120489.html