( ext{bibi}) 时间到!
这种题我能想出来就有鬼了。
题目
解法
有一个先导结论 ——
假设选取的三角形集合为 (S),那么 (S) 中三角形相交形成的三角形的面积为:
[f(S)=frac{1}{2}(min{x_i+y_i+r_i}-max x_i-max y_i) ]
具体证明的话,懒得画图,就用文字叙述吧:
- (x_i+y_i+r_i) 能表示三角形 (i) 斜边形成直线的截距。
- 相交三角形的斜边截距最小,左下角横纵坐标均为最大。
枚举所选三角形集合进行容斥:
[ ext{Ans}=sum_{empty subsetneq Ssubseteq U}g(|S|)cdot f(S)
]
其中 (g) 是要算的容斥系数,它一般只与所选集合 大小 有关。
类似容斥原理的证明,我们设某个三角形被 (m) 个三角形包含,就有:
[sum_{i=1}^m inom{m}{i}cdot g(i)=[2
mid m]
]
左边那个很像二项式反演,于是我们令 (h(m)=[2 mid m])。就有:
[h(m)=sum_{i=1}^m inom{m}{i}cdot g(i)
]
[g(m)=sum_{i=1}^m (-1)^{m-i} inom{m}{i}h(i)
]
[g(m)=sum_{i=1}^m (-1)^{m-i} inom{m}{i}[2
mid i]
]
推到这里应该就可以了,我没有试过,可以预处理一下 (g)。
不过其实还可以化简。虽然 ([2 mid i]) 看上去很难搞,但有一个这样的式子:
[(a+b)^n-(a-b)^n=sum_{i=0}^ninom{n}{i}a^{n-i}b^{i}-sum_{i=0}^n(-1)^{i}inom{n}{i}a^{n-i}b^{i}
]
[=2sum_{i=0}^n [2
mid i]inom{n}{i}a^{n-i}b^i
]
((-1)^{m-i}) 肿么办呢?由于只有 ([2 mid i]) 有贡献,所有的 ((-1)^{m-i}) 都相当于 ((-1)^{m-1}),而且还可以添一个 (i=0)。所以可以改写为:
[g(m)=(-1)^{m-1}sum_{i=0}^m [2
mid i]inom{m}{i}
]
[=(-1)^{m-1} imes frac{(1+1)^m-(1-1)^m}{2}=(-2)^{m-1}
]
然后直接枚举集合计算贡献。时间复杂度 (mathcal O(ncdot2^n))。另外那个神仙三维差分还是算了吧。而且这题暴力数三角形完全可过好吧!
代码
#include <cstdio>
#define print(x,y) write(x),putchar(y)
template <class T>
inline T read(const T sample) {
T x=0; char s; bool f=0;
while((s=getchar())>'9' or s<'0')
f|=(s=='-');
while(s>='0' and s<='9')
x=(x<<1)+(x<<3)+(s^48),
s=getchar();
return f?-x:x;
}
template <class T>
inline void write(const T x) {
if(x<0) {
putchar('-'),write(-x);
return;
}
if(x>9) write(x/10);
putchar(x%10^48);
}
#include <iostream>
using namespace std;
const int maxn=1300,inf=1e7;
int x[20],y[20],r[20],c[20];
int n,Pow[maxn];
int main() {
n=read(9);
for(int i=1;i<=n;++i)
x[i]=read(9),y[i]=read(9),
r[i]=read(9),c[i]=x[i]+y[i]+r[i];
Pow[0]=1;
for(int i=1;i<=n;++i)
Pow[i]=Pow[i-1]*(-2);
double ans=0;
for(int i=0;i<(1<<n);++i) {
int minc=inf,maxx=-inf,maxy=-inf,cnt=0;
for(int j=1;j<=n;++j)
if(i>>j-1&1)
++cnt,
minc=min(minc,c[j]),
maxx=max(maxx,x[j]),
maxy=max(maxy,y[j]);
if(minc-maxx-maxy>=0)
ans+=1.0*(minc-maxx-maxy)*(minc-maxx-maxy)/2*Pow[cnt-1];
}
printf("%.1f
",ans);
return 0;
}