zoukankan      html  css  js  c++  java
  • BZOJ 1176: [Balkan2007]Mokia

    一道CDQ分治的模板题,然而我De了一上午Bug......

    按时间分成左右两半,按x坐标排序然后把y坐标丢到树状数组里,扫一遍遇到左边的就add,遇到右边的query

    几个弱智出了bug的点,

    一是先分了左右两半再排序,保证的是这次的左右是上次没有计算过的贡献,

    for(int i=l;i<=r;i++) qs[i].k=(i>mid);
        sort(qs+l,qs+r+1,cmp2);

    然后时间的先后是因为一开始就是按时间排好序的已经保证了。

    二是矩阵的一个经典的套路就是拆成四部分差分查询。

    三是很智障的,树状数组要注意y==0的情况

    四是比较重要的,比较的时候条件要加充分,之前写陌上花开也出现了这个问题,一维还是两维相同就不管了,会爆炸。。。一定要考虑清楚所有会影响的维,都要加入排序条件中

    bool cmp2(const node&a,const node&b) {
        return a.x<b.x||(a.x==b.x&&(a.y<b.y||(a.y==b.y&&bo[a.id]<bo[b.id])));
    }

    还有,数组大小要开够,在下RE好像大半都是数组问题。。

    //Twenty
    #include<cstdio>
    #include<cstdlib>
    #include<iostream>
    #include<algorithm>
    #include<cmath>
    #include<cstring>
    #include<queue>
    #include<vector>
    #define mid ((l+r)>>1)
    using namespace std;
    const int maxn=200000+299;
    const int maxw=2000000+29;
    int tot,s,w,opt,x,y,x2,y2,a,sg[maxw],bo[maxn],ans,cnt;
    struct node{
        int x,y,v,id,sum,k;
        node(){sum=0;};
        node(int x,int y,int v,int id):x(x),y(y),v(v),id(id){sum=0;}
    }qs[maxn];
    bool cmp1(const node&a,const node&b) {
        return a.id<b.id;
    }
    bool cmp2(const node&a,const node&b) {
        return a.x<b.x||(a.x==b.x&&(a.y<b.y||(a.y==b.y&&bo[a.id]<bo[b.id])));//!!!!!!!
    }
    void add(int x,int v) {
        for(int i=x;i<=w;i+=(i&(-i))) 
           sg[i]+=v; 
    }
    int qry(int x) {
        int res=0;
        for(int i=x;i>0;i-=(i&(-i))) 
            res+=sg[i];
        return res;
    }
    void solve(int l,int r) {
        if(l==r) return ;
        solve(l,mid); solve(mid+1,r);
        for(int i=l;i<=r;i++) qs[i].k=(i>mid);
        sort(qs+l,qs+r+1,cmp2);
        for(int i=l;i<=r;i++) {
            if(bo[qs[i].id]&&qs[i].k) {
                if(qs[i].y) qs[i].sum+=qry(qs[i].y);
            }
            else if(!bo[qs[i].id]&&!qs[i].k) {
                if(qs[i].y ) add(qs[i].y,qs[i].v);
            }
        }
        for(int i=l;i<=r;i++) 
            if(!bo[qs[i].id]&&!qs[i].k) {
                if(qs[i].y) add(qs[i].y,-qs[i].v); 
            }
    }
    int main()
    {
        scanf("%d%d",&s,&w);
        for(;;) {
            scanf("%d",&opt); 
            if(opt==3) break;
            if(opt==1) {
                scanf("%d%d%d",&x,&y,&a);
                qs[++tot]=node(x,y,a,tot);
            }
            else {
                scanf("%d%d%d%d",&x,&y,&x2,&y2);
                qs[++tot]=node(x-1,y-1,1,tot);
                qs[++tot]=node(x-1,y2,-1,tot-1);
                qs[++tot]=node(x2,y-1,-1,tot-2);
                qs[++tot]=node(x2,y2,1,tot-3);
                bo[tot-3]=1;//是询问 
            }
            
        }
        solve(1,tot);
        sort(qs+1,qs+tot+1,cmp1);
        for(int i=1;i<=tot;i++) 
        if(bo[qs[i].id]){
            cnt++;
            ans+=qs[i].sum*qs[i].v;
            if(cnt==4) {
                printf("%d
    ",ans);
                ans=0,cnt=0;
              }  
        }
        return 0;
    }
    1176: [Balkan2007]Mokia

     吐槽一句为什么都是权限题呀。。

  • 相关阅读:
    POJ 1141 括号匹配 DP
    881. Boats to Save People
    870. Advantage Shuffle
    874. Walking Robot Simulation
    文件操作
    861. Score After Flipping Matrix
    860. Lemonade Change
    842. Split Array into Fibonacci Sequence
    765. Couples Holding Hands
    763. Partition Labels
  • 原文地址:https://www.cnblogs.com/Achenchen/p/7477567.html
Copyright © 2011-2022 走看看