CF815D Karen and Cards 单调栈+扫描线

非常好的一道题.     

我们考虑枚举哪些三元组不能成为答案.   

然后你发现这成了一个立方体并问题.     

通过枚举 $c$ ,可以将问题转化为二维矩形并问题.     

由于从大到小枚举 $c$,所以并是不断增大的,然后增大的话就会让 $a/b$ 延伸到极大值位置. 

所以只有 $a,b$ 是单调的,才会对答案有影响,这么更新就行了. 

code: 

#include <bits/stdc++.h> 
#define N 500020  
#define ll long long 
#define setIO(s) freopen(s".in","r",stdin)   
using namespace std;
ll ans,sum;   
int n,A,B,C,top,tx,ty;    
int st[N],x[N],y[N];  
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 main() 
{ 
    // setIO("input");  
    int i,j;  
    scanf("%d%d%d%d",&n,&A,&B,&C);   
    for(i=1;i<=n;++i) 
        scanf("%d%d%d",&p[i].a,&p[i].b,&p[i].c);      
    sort(p+1,p+1+n,cmpa);     
    for(i=1;i<=n;++i) 
    {
        while(top&&p[i].b>p[st[top]].b) --top;    
        st[++top]=i;   
    }
    sum=(ll)A*B,st[top+1]=0;   
    for(i=1;i<=top;++i) 
    {
        sum-=(ll)(p[st[i]].a-p[st[i-1]].a)*p[st[i]].b;     
        for(j=p[st[i-1]].a+1;j<=p[st[i]].a;++j) y[j]=p[st[i]].b; 
        for(j=p[st[i]].b;j>p[st[i+1]].b;--j) x[j]=p[st[i]].a;    
    }
    sort(p+1,p+1+n,cmpc);     
    for(tx=ty=j=1,i=C;i;--i) 
    {
        for(;j<=n&&p[j].c>=i;++j) 
        {
            for(;tx<=p[j].a;++tx) sum-=B-max(y[tx],ty-1);     
            for(;ty<=p[j].b;++ty) sum-=A-max(x[ty],tx-1);  
        }
        ans+=sum;  
    }
    printf("%lld\n",ans);    
    return 0;  
}

  

猜你喜欢

转载自www.cnblogs.com/guangheli/p/12397091.html