P4515 [COCI2009-2010#6] XOR

[COCI2009-2010#6] XOR

题目描述

坐标系下有若干个等腰直角三角形,且每个等腰直角三角形的直角顶点都在左下方,两腰与坐标轴平行。被奇数个三角形覆盖的面积部分为灰色,被偶数个三角形覆盖的面积部分为白色,如下图所示。

已知 N个等腰直角三角形的顶点坐标及腰长,求灰色部分面积。

1N10,1X,Y,R106

思路点拨

容斥做法

这题的数据范围十分的明显, n=10 ,搜索,状压,容斥什么的。再加上本题的题目配图,很容易往容斥的角度思考问题。本题具体有两种容斥做法:

第一种(不好想但是简单)

我们假设一片区域被 m 个三角形包含,这 m 个三角形共同组成了一个集合 S
有一个结论:

[2m]=TS(1)|T|+12|T|1

这里给出一个简单的证明:

TS(1)|T|+12|T|1=i=1|S|Cmi(1)i+12i1

(1)i+1=(1)i1 本质上是一样的,方便与后面的 2i1 同类项。

=i=1mCmi(1)i12i1=i=1mCmi(2)i1

这个东东有点像 (2+1)m 的二项式定理展开式,我们将 (2)i1 凑成 (2)i , 然后二项式定理减去 i=0 的贡献就可以了。

=12i=1mCmi(2)i=i=0mCmi(2)i12

=1(2+1)m2=[2m]

OK,我们就获得了一个容斥系数。代码实现比较简单。

第二种(好想,二项式反演)

我们令 f(m) 表示 m 的容斥系数, g(m)=[2m]

那么应该有 g(m)=i=1mCmif(i)

二项式反演得:

f(m)=i=0m(1)miCmig(i)

其实以上两种方法得到的容斥系数是一样的,至于为什么是一样的,留给读者自己思考。可以从杨辉三角或者组合恒等式的角度进行思考。

以上的两种做法都需要使用多个三角形求交,初中数学自己推一下,这里给出代码:

code

#include<bits/stdc++.h>
#define int long long
using namespace std;
inline int read(){
	int x=0,f=1;
	char ch=getchar();
	while(ch<'0'||ch>'9'){
		if(ch=='-') f=-f;
		ch=getchar();
	}
	while(ch>='0'&&ch<='9'){
		x=x*10+ch-'0';
		ch=getchar();
	}
	return x*f;
}
const int MAXN=11;
int n;
struct node{
	int x,y,w;
}a[MAXN];
int siz(node A){
	return A.w*A.w;
}
node insert(node A,node B){
	node C;
	C.x=max(A.x,B.x);
	C.y=max(A.y,B.y);
	C.w=max((int)0,min(A.x+A.y+A.w,B.x+B.y+B.w)-C.x-C.y);
	return C;
}
signed main(){
	n=read();
	for(int i=1;i<=n;i++){
		a[i].x=read(),a[i].y=read();
		a[i].w=read();
	}
	int ans=0; 
	for(int i=1;i<(1<<n);i++){
		node temp;
		int flag=0,popcount=0;
		for(int j=0;j<n;j++){
			if(!(i&(1<<j))) continue;
			popcount++;
			if(!flag){
				temp=a[j+1];
				flag=1;
			} 
			else temp=insert(temp,a[j+1]);
		}
		if(popcount&1) ans+=(siz(temp)<<popcount);
		else ans-=(siz(temp)<<popcount);
	}
	printf("%.1lf",1.0*ans/4);
	return 0;
}
posted @   Diavolo-Kuang  阅读(229)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!
点击右上角即可分享
微信分享提示