• CF815D Karen and Cards


    CF815D Karen and Cards 

    固定一维c,然后(a,b)看成坐标,矩形区域求交

    1.Segment tree Beats!

    2.改成不合法的区域就是求并,c反向枚举,区域只增不减且完全包含之前的

    单调栈预处理找到轮廓线,然后两个指针维护顶头位置即可

    #include<bits/stdc++.h>
    #define reg register int
    #define il inline
    #define int long long
    #define numb (ch^'0')
    using namespace std;
    typedef long long ll;
    il void rd(int &x){
        char ch;x=0;bool fl=false;
        while(!isdigit(ch=getchar()))(ch=='-')&&(fl=true);
        for(x=numb;isdigit(ch=getchar());x=x*10+numb);
        (fl==true)&&(x=-x);
    }
    namespace Miracle{
    const int N=500000+5;
    int n,A,B,C;
    ll ans,sum;
    struct node{
        int a,b,c;
    }p[N];
    bool cmpa(node a,node b){
        return a.a<b.a;
    }
    bool cmpc(node a,node b){
        return a.c>b.c;
    }
    int sta[N],top;
    int x[N],y[N];
    int main(){
        rd(n);rd(A);rd(B);rd(C);
        for(reg i=1;i<=n;++i) rd(p[i].a),rd(p[i].b),rd(p[i].c);
        sort(p+1,p+n+1,cmpa);
        for(reg i=1;i<=n;++i){
            while(top&&p[sta[top]].b<p[i].b) --top;
            sta[++top]=i;
        }
        sum=(ll)A*B;
        sta[top+1]=0;
        for(reg i=1;i<=top;++i){
            //cout<<" ii "<<i<<" "<<p[sta[i]].b<<endl;
            sum-=(ll)((ll)p[sta[i]].a-p[sta[i-1]].a)*p[sta[i]].b;
            for(reg j=p[sta[i-1]].a+1;j<=p[sta[i]].a;++j) x[j]=p[sta[i]].b;
            for(reg j=p[sta[i]].b;j>p[sta[i+1]].b;--j) y[j]=p[sta[i]].a;
        }
    //    for(reg i=1;i<=A;++i){
    //        cout<<x[i]<<" ";
    //    }cout<<endl;
    //    for(reg i=1;i<=B;++i){
    //        cout<<y[i]<<" ";
    //    }cout<<endl;
    //    cout<<" sum "<<sum<<endl;
        sort(p+1,p+n+1,cmpc);
        for(reg tx=1,ty=1,j=1,i=C;i>=1;--i){
        //    cout<<" i "<<i<<" tx "<<tx<<" ty "<<ty<<endl;
            while(j<=n&&p[j].c>=i){
            //    cout<<" p[j] "<<j<<" "<<p[j].c<<endl;
                for(;tx<=p[j].a;++tx) sum-=B-max(ty-1,x[tx]);
            //    cout<<" sum1 "<<sum<<endl;
                for(;ty<=p[j].b;++ty) sum-=A-max(tx-1,y[ty]);
            //    cout<<" sum2 "<<sum<<endl;
                ++j;
            }
            ans+=sum;
        }
        printf("%lld",ans);
        return 0;
    }
    
    }
    signed main(){
        Miracle::main();
        return 0;
    }
    
    /*
       Author: *Miracle*
       Date: 2019/3/3 15:45:41
    */

    很套路了

    排序,然后偏序想到坐标矩形求面积

    交和并的转化,容斥。或者大力吉司机线段树

  • 相关阅读:
    JSP动作元素你又知几多?
    一个简单的TCP/IP服务端客户端对话
    使用Graphics2D去除曲线锯齿状
    MySQL数据类型
    Eclipse常用快捷键
    C#中的委托和事件
    GitHub当道,菜鸟也为Git疯狂
    C++文件操作
    JSP指令你知多少?
    spring如何使用多个xml配置文件
  • 原文地址:https://www.cnblogs.com/Miracevin/p/10483513.html
Copyright © 2020-2023  润新知