• bzoj4237稻草人


    传送门

    写了一中午,被自己瓜得无话可说。

    cdq的题,然后开始脑补。

    写了第一个版本是考虑一半对另一半的贡献,贡献的那一遍维护单调性,没有考虑查询的一半的点之间的影响,一直偏大,14pt。

    卡掉的数据:

    5

    1 5

    5 4

    2 1

    3 2

    4 3

    然后不知道如何脑抽地写了第二个版本,树状数组乱搞,从挡住的地方往上在数组数组里减,然后被重复挡的部分会被多减,一直偏小,31pt

    卡掉的数据

    5

    1 1

    4 2

    2 3

    5 4

    5 5

    最终屈服于题解,,智商堪忧,,

    按x排序,按y分治,考虑下一半对上一半的影响,上一半维护单增的单调栈,相当于知道这个查询点前一个挡住它的点的位置pos,从该点往后的单减的栈就是答案。

    于是下一半维护单减的栈,二分找到其中第一个x大于pos的x的位置,往后的栈大小就是答案。

    //Achen
    #include<algorithm>
    #include<iostream>
    #include<cstring>
    #include<cstdlib>
    #include<cstdio>
    #include<vector>
    #include<queue>
    #include<ctime>
    #include<cmath>
    const int N=2e5+7;
    typedef long long LL;
    using namespace std;
    int n,xx[N],yy[N],q1[N],q2[N],top1,top2;
    LL ans;
    
    template<typename T> void read(T &x) {
        char ch=getchar(); x=0; T f=1;
        while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar();
        if(ch=='-') f=-1,ch=getchar();
        for(;ch>='0'&&ch<='9';ch=getchar()) x=x*10+ch-'0'; x*=f;
    }
    
    struct node{
        int x,y;
        friend bool operator <(const node&A,const node &B) {
            return A.x<B.x;
        }
    }p[N],tp[N];
    
    int ef(int x) {
        int l=1,r=top1,res=0;
        while(l<=r) {
            int mid=((l+r)>>1);
            if(p[q1[mid]].x>x) res=mid,r=mid-1;
            else l=mid+1;
        }
        if(res!=0) res=top1-res+1;
        return res;
    }
    
    void cdq(int l,int r) {
        if(l==r) return; 
        int mid=((l+r)>>1),ql=l-1,qr=mid;
        top1=top2=0;
        for(int i=l;i<=r;i++) {
            if(p[i].y<=mid) {
                tp[++ql]=p[i];
                while(top1&&p[q1[top1]].y<p[i].y) top1--;
                q1[++top1]=i;
            }
            else {
                tp[++qr]=p[i];
                while(top2&&p[q2[top2]].y>p[i].y) top2--;
                ans+=ef(p[q2[top2]].x);
                q2[++top2]=i;
            }
        }
        for(int i=l;i<=r;i++) p[i]=tp[i];
        cdq(l,mid); cdq(mid+1,r); 
    }
    
    #define DEBUG 
    int main() {
    #ifdef DEBUG
        freopen("scarecrows.in","r",stdin);
        freopen("scarecrows.out","w",stdout);
    #endif
        read(n);
        for(int i=1;i<=n;i++) {
            read(p[i].x); read(p[i].y);
            xx[i]=p[i].x;
            yy[i]=p[i].y;
        }
        sort(xx+1,xx+n+1);
        sort(yy+1,yy+n+1);
        for(int i=1;i<=n;i++) {
            p[i].x=lower_bound(xx+1,xx+n+1,p[i].x)-xx;
            p[i].y=lower_bound(yy+1,yy+n+1,p[i].y)-yy;
        }
        sort(p+1,p+n+1);
        cdq(1,n);
        printf("%lld
    ",ans);
        return 0;
    }
    View Code

     

    不管怎么说,bzojSolved数终于突破两位数了,留恋一下,可喜可贺可喜可贺。

  • 相关阅读:
    在不同浏览器都实用的各窗口大小获取方法
    line-height,vertical-align及图片居中对齐问题根源解析
    浅谈语义化
    有关于界面设计的技巧
    图片无缝滚动
    office 所有后缀对应的 content-type
    原生js删除增加修改class属性
    使用 colgroup 和 col 实现响应式表格
    js 监控浏览器关闭事件
    document.documentElement.scrollTop(获取滚动条位置)
  • 原文地址:https://www.cnblogs.com/Achenchen/p/8080789.html
Copyright © 2020-2023  润新知