非常好的一道题.
我们考虑枚举哪些三元组不能成为答案.
然后你发现这成了一个立方体并问题.
通过枚举 $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; }