【FCS NOI2018】福建省冬摸鱼笔记 day3

第三天。

计算几何,讲师:叶芃(péng)。

dalao们日常不记笔记。@ghostfly233说他都知道了,就盼着自适应辛普森积分。

我计算几何基础不好……然而还是没怎么讲实现,感觉没听什么东西进去。

不过还是记了一些公式。

同时@ghostfly233在后面打农药。

然后讲到了有关圆的东西。讲完了,下课了。辛普森有兴趣的同学回去自己看看吧。

辛普森:???

@ghostfly233非常难受。



中午划水。



下午有一题和早上的有关。

T1半平面交+面积,简单题,我半平面交写错了,只有80。

T2神秘图论结论+神秘数学/神秘DP,那个结论第一天就接触过了,然而我不知道放那儿有啥用,于是不会做,其实再证一个结论就简单状压DP了。

T3毒瘤分治啥的,没想法,搞了个最坏\(O(n^2)\)的RMQ,结果70分???@qrc和我差不多,只有30分,因为他预处理\(O(n^2)\),233333。数据出水了。

150分比较舒服。

【T1】

题面:求一个凸包内部,随机取点P,使得P与给定一边组成的三角形,比P与其他边组成的三角形面积都要小,取到这样的点P的概率。

题解:一看就是半平面交再算面积,算出给定边和其他边的那条直线(使得P在直线一侧,三角形更小),交一交就好了。

难点在于如何求出直线,其实推推式子就没问题,第二个是半平面交,我写挂了,幸好不是什么严重错误,于是80分。

#include<cstdio>
#include<cmath>
#include<algorithm>
#define db double
using namespace std;
const db eps=1e-10;
struct vec{db x,y;vec(db x=0,db y=0):x(x),y(y){}};
inline vec operator+(vec x,vec y){return vec(x.x+y.x,x.y+y.y);}
inline vec operator-(vec x,vec y){return vec(x.x-y.x,x.y-y.y);}
inline vec operator*(db  x,vec y){return vec(x*y.x,x*y.y);}
inline vec operator*(vec x,db  y){return vec(y*x.x,y*x.y);}
inline db operator *(vec x,vec y){return x.x*y.y-x.y*y.x;}
inline db mod(vec x){return sqrt(x.x*x.x+x.y*x.y);}
inline bool zero(db x){if(x<=eps&x>=-eps)return 1;return 0;}
struct line{vec p,v;line(vec p=vec(0,0),vec v=vec(0,0)):p(p),v(v){}};
inline bool cmp(line x,line y){return atan2(x.v.y,-x.v.x)<atan2(y.v.y,-y.v.x);}
void print(vec x){printf("(%lf, %lf)",x.x,x.y);}
void print(line x){print(x.p);printf(" -> ");print(x.v);puts("");}
inline vec jiao(line x,line y){
	return x.p+((((y.p-x.p)*y.v)/(x.v*y.v))*x.v);
}
inline line clac(line x,line y){
	if(zero(x.v*y.v)) return line(y.p+((x.p-y.p)*(mod(x.v)/(mod(x.v)+mod(y.v)))),x.v-y.v);
	return line(jiao(x,y),x.v-y.v);
}
inline bool left(line x,vec y){
	return (x.v*(y-x.p))>-eps;
}
int n,cnt; db ans1,ans2;
vec dots[100001];
line edge[100001];
line edg2[200001];
line que[200001];int l=1,r=0;
int main(){
	freopen("convex.in","r",stdin);
	freopen("convex.out","w",stdout);
/*	while(1){
		line p1,p2;
		line v;
		scanf("%lf%lf%lf%lf%lf%lf%lf%lf",&p1.p.x,&p1.p.y,&p1.v.x,&p1.v.y,&p2.p.x,&p2.p.y,&p2.v.x,&p2.v.y);
		print(p1); print(p2);
		v=clac(p1,p2);
		print(v);
	}*/
	scanf("%d",&n);
	for(int i=1;i<=n;++i) scanf("%lf%lf",&dots[i].x,&dots[i].y);
//======
	ans1+=dots[n]*dots[1];
	for(int i=1;i<n;++i) ans1+=dots[i]*dots[i+1];
	ans1/=2; ans1=abs(ans1);
//======
	for(int i=1;i<n;++i) edge[i]=line(dots[i],dots[i+1]-dots[i]);
	edge[n]=line(dots[n],dots[1]-dots[n]);
	edg2[++cnt]=line(dots[1],dots[n]-dots[1]);
	for(int i=2;i<=n;++i) edg2[++cnt]=line(dots[i],dots[i-1]-dots[i]);
	for(int i=2;i<=n;++i) edg2[++cnt]=clac(edge[1],edge[i]);
	sort(edg2+1,edg2+cnt+1,cmp);
//======
//	puts("======");
//	for(int i=1;i<=cnt;++i) print(edg2[i]);
//	puts("======");
//======
	que[++r]=edg2[1]; que[++r]=edg2[2];
	for(int i=3;i<=cnt;++i){
//		puts("######");
//		for(int j=l;j<=r;++j) print(que[j]);
//		puts("######");
		while(l<=r-1&&left(edg2[i],jiao(que[r],que[r-1]))) --r;
		while(l<=r-1&&left(edg2[i],jiao(que[l],que[l+1]))) ++l;
		if(zero(que[r].v*edg2[i].v)){
			if(l<=r-1&&left(edg2[i],jiao(que[r],que[r-1]))) --r;
			else continue;
		}
		que[++r]=edg2[i];
	}
	while(l<=r-1&&left(edg2[l],jiao(que[r],que[r-1]))) --r;
//======
//	puts("======");
//	for(int i=l;i<=r;++i) print(que[i]);
//	puts("======");
//======
	if(l==r-1) ans2=0;
	else{
		ans2+=jiao(que[l],que[l+1])*jiao(que[l],que[r]);
		ans2+=jiao(que[r],que[l])*jiao(que[r],que[r-1]);
		for(int i=l+1;i<=r-1;++i) ans2+=jiao(que[i],que[i+1])*jiao(que[i],que[i-1]);
		ans2/=2; ans2=abs(ans2);
	}
//======
	printf("%.4f",ans2/ans1);
	return 0;
}

【T2】

题意:给定一个二分图G={V=X+Y,E},每个点有价值,求有多少个V的子集S的价值大于等于给定的t,并且S可以被原图G中的一个匹配覆盖。\(|X|,|Y|\leq 20\)

题解:Hall定理:对于一个二分图G={X+Y,E},那么存在一个能覆盖X的匹配当且仅当对于任意一个X的子集,从它引边到Y后,Y被覆盖的点的数量大于等于这个子集的点的数量。

那么,还要证明一个结论:对于二分图G={X+Y,E},如果X的子集P能被一个G的匹配MP覆盖,Y的子集Q能被一个G的匹配MQ覆盖,那么G必有一个匹配能覆盖P+Q。

为什么呢?如果P中的一个点通过MP到达Y的点不在Q中,那这条边就可以选取,因为P没有另一个点通过MP能到达同一个点;反之,如果在Q中,那这个点再通过MQ到达X,重复这个过程,最后会形成一条链或一个环,在链中的话我们隔着取边,不论长度为奇数或偶数都可以取到,如果是一个环,那么必须是一个偶环,因为是二分图,所以我们仍然隔着取边就好了。

那么我们要做的是:①处理X,Y中的每个子集是否有匹配能覆盖它,②把可以的按照价值排序,③双指针扫一遍。

①可以用状压DP解决。

#include<cstdio>
#include<algorithm>
using namespace std;
int n,m,t,s,num[1048576],A[1048576],B[1048576],vA[1048576],vB[1048576],sA[1048576],sB[1048576],cA,cB;
bool fA[1048576],fB[1048576];
long long ans;
int main(){
	freopen("match.in","r",stdin);
	freopen("match.out","w",stdout);
	scanf("%d%d",&n,&m); s=n>m?n:m;
	for(int i=1;i<1<<s;++i) num[i]=num[i-(i&-i)]+1;
	char ch;
	for(int i=0;i<n;++i) for(int j=0;j<m;++j)
		ch=getchar(), ch==‘1‘?A[1<<i]|=1<<j,B[1<<j]|=1<<i:ch!=‘0‘?--j:0;
	for(int i=0;i<1<<n;++i) A[i]=A[i&-i]|A[i-(i&-i)];
	for(int i=0;i<1<<m;++i) B[i]=B[i&-i]|B[i-(i&-i)];
	for(int i=0;i<n;++i) scanf("%d",vA+(1<<i));
	for(int i=0;i<m;++i) scanf("%d",vB+(1<<i));
	for(int i=0;i<1<<n;++i) vA[i]=vA[i&-i]+vA[i-(i&-i)];
	for(int i=0;i<1<<m;++i) vB[i]=vB[i&-i]+vB[i-(i&-i)];
	for(int i=0;i<1<<n;++i){
		if(num[A[i]]<num[i]) continue;
		fA[i]=1;
		for(int j=0;j<n;++j) if(i>>j&1)
			fA[i]&=fA[i^1<<j];
		fA[i]?sA[cA++]=vA[i]:0;
	} sort(sA,sA+cA);
	for(int i=0;i<1<<m;++i){
		if(num[B[i]]<num[i]) continue;
		fB[i]=1;
		for(int j=0;j<n;++j) if(i>>j&1)
			fB[i]&=fB[i^1<<j];
		fB[i]?sB[cB++]=vB[i]:0;
	} sort(sB,sB+cB);
	scanf("%d",&t);
	for(int i=0,j=cB;i<cA;++i){
		while(j>0&&sA[i]+sB[j-1]>=t) --j;
		ans+=cB-j;
	}
	printf("%lld",ans);
	return 0;
}

原文地址:https://www.cnblogs.com/PinkRabbit/p/8456364.html

时间: 2024-08-30 00:31:28

【FCS NOI2018】福建省冬摸鱼笔记 day3的相关文章

【FCS NOI2018】福建省冬摸鱼笔记 day1

省冬的第一天. 带了本子,笔,一本<算法导论>就去了.惊讶于为什么同学不带本子记笔记. 他们说:"都学过了.",果然这才是巨神吧. 第一天:数论,讲师:zzx 前几页的课件挺水,瞎记了点笔记.后面直接就讲了两道题,我就没想出来,真的菜. 然后学了波原根,又听不太懂. 莫比乌斯反演,又听不太懂.然而我自己瞎推式子好像就能反演出来,没想法XD. 杜教筛,又听不太懂. 线性代数,zzx干脆不讲了,没想法.反正也不是数论范畴. 第一天的早晨就这么过去了,@qrc去AMC10了,没想

【FCS NOI2018】福建省冬摸鱼笔记 day2

第二天. 同学还是不带本子记笔记.dalao. 第二天:图论,讲师:@ExfJoe 全程划水,前面都讲水算法[虽然我可能已经忘记了]什么最短路,Tarjan,最小生成树,2SAT,差分约束啥的,我现在肯定写不出来啦. 后面题目也还挺好,可能是听的比较懂的一天吧.不过也很有挑战性. 中午划水 还以为下午的题目会和上午有关系,事实证明我想太多. T1想了个错误分块,写了n久挂了,不想调,正解主席树. T2简单数学题,瞎推式子就完了,后悔没有去做啊. T3毒瘤模拟题,什么切比雪夫,什么曼哈顿,什么奇偶

【FCS NOI2018】福建省冬摸鱼笔记 day6【FJOI 2018】福建省选混分滚蛋记 day1

记录一下day6发生的事情吧. 7:30 到达附中求索杯,被人膜,掉RP. 7:50 进考场,6楼的最后一排的最左边的位置,世界上最角落的地方,没有任何想法. 发现电脑时间和别人不一样,赶快调了一下. 8:00 等待发题. 8:03 题发了,为什么要迟发呢.=) 8:05-9:30 冥思苦想T1什么鬼东西.中间看了看T2T3是啥. 9:30-10:30 对T3的水震惊之余,把T3切掉了,顺便在准考证背面写了题解,准备给同学看看,以便带出去交流. 10:50-12:00 思考T2骗分,T2又是DN

【FCS NOI2018】福建省冬摸鱼笔记 day4

第四天. 动态规划专题,讲师:闫神 讲了一些DP优化技巧,然而思想难度好大啊--根本没想到能优化那地步,连DP方程都没有呢. 不过有几题我还是想明白了. 讲了单调队列,决策单调性,四边形不等式,斜率优化,甚至有DP套DP,然而就是双重DP,什么背包+数位罢了. 轮廓线DP,插头DP都有点难写啊--不过也是状压DP的一大内容 .还有概率DP,期望DP,非常恐怖. 中午划水. 下午的题比较良心.T1不知道写了什么写挂了,T2就很好AC,T3毒瘤题. [T1] 题面:m个青蛙,它们可以跳无限远,但是第

[日常摸鱼]Uva11178Morley&#39;s Theorem-几何

题意:给一个$\Delta ABC$,分别做三个角的三等分线相交成$\Delta DEF$,求出$D,E,F$的坐标. 直接根据题意模拟 #include<cstdio> #include<cmath> #include<algorithm> using namespace std; struct Point { double x,y; Point(double x1=0,double y1=0){x=x1;y=y1;} }; typedef Point Vector;

转:用 Python 一键分析你的上网行为, 看是在认真工作还是摸鱼

简介 想看看你最近一年都在干嘛?看看你平时上网是在摸鱼还是认真工作?想写年度汇报总结,但是苦于没有数据?现在,它来了. 这是一个能让你了解自己的浏览历史的Chrome浏览历史记录分析程序,当然了,他仅适用于Chrome浏览器或者以Chrome为内核的浏览器. 在该页面中你将可以查看有关自己在过去的时间里所访问浏览的域名.URL以及忙碌天数的前十排名以及相关的数据图表. 部分截图 代码思路 1. 目录结构 首先,我们先看一下整体目录结构 Code ├─ app_callback.py 回调函数,实

摸鱼鬼混的英文怎么说 ?

摸鱼鬼混的英文怎么说 (引用来源.世界公民文化中心) 如果你是老板,你会"hire"哪种员工? 以下这两种人stepford worker(糊涂死忠型)和clocksucker(摸鱼鬼混型)的人,想想身边的同事,你是不是觉得似曾相识? Stepford Worker Stepford一词来自于小说 The Stepford Wives,也有被制作成同名电影,中国台湾译为<超完美娇妻>,由妮可基嫚(Nicole Kidman)主演.故事描述纽约市郊区一个小镇里,有一群完美的贤

操作系统课程设计摸鱼全纪录

读了几年,都没留下什么东西方便学弟学妹借鉴.感觉这个大三上学期的操作系统课程设计恰好在寒假,大概是最后一次机会了,写点东西. 首先老师要求用的是: ubuntu-18.04 fuse-2.7.0 这种事情当然是使用虚拟机啦!下载并安装VMware,然后下载并安装ubuntu-18.04,拷贝老师给的fuse-2.7.0进去解压.找找看怎么安装. 看了一圈,发现有个README是看得懂的,里面有很多话,我相信来看我博客的人也是摸鱼混及格的,那当然只关心下面的: 那么打开一个Terminal,输入对

FFT 深夜摸鱼小笔记

本次笔记学习自算法导论 FFT核心:系数表示→(单位复数根)点值表示→(插值)系数表示 关于单位复数根 n次单位复数根\(ω\)为满足\(ω^n=1\)的复数 n次单位复数根恰好有n个,表示为\(ω_k,k=0,1,...n-1\) 由欧拉公式\(e^{iθ}=cosΘ+isinΘ\),得\(ω_k=e^{i2πk/n}\) 主n次单位根\(ω_n=e^{2πi/n}\),其他n次单位复数根都是\(ω_n\)的幂次,表示为\(ω_n^k,k=0,1,...n-1\) \(ω_n^n=ω_n^0\