SDOI 2018 R2 自我总结

DAY1 

       由于蒟蒻一轮省选爆炸CE,二轮上了考场之后并不是很慌,先看了看第一道题,感觉很可做,然后几乎整场比赛就栽在第一道题上了.... 第一眼的思路就是现将整个坐标系按照给定直线导轨的角度翻转,然后将挡板(线段)映射到导轨上,然后处理一下导轨之间的遮挡情况,注意到最后选取的区间左右端点一定有一个会卡在挡板的端点上,所以可以O(n)统计答案。
       感觉很难码,然后就赶紧开始码。。。
       诶 , 坐标翻转公式是啥嘞? 我去推一推。。。 一个小时过去了。。。
       诶 , 怎么我只会n方预处理遮挡情况呢? 哇, 只有40分了。。
       心态爆炸。。。
       大概码了三个小时调过大样例,然后自信看第二题了。
       woc!怎么t2我连暴力都不会!! 考完知道这是WC讲的圆方树,后悔没去。还是因为我姿势水平太低了唉....
       t3唐题没什么思路。。。。
考完期望得分40 实际0 唉我代码炒鸡弱啊 真的是很气 后来发包之后发现我没有处理两个线段端点相同情况,加了个=号就40了

然后赛后在zyb dalao 指导下知道了可以用扫描线这种东西,然后赛后写出来100了。。
总结:不要太相信大样例,太坑了!!!!!!!

DAY2
    day1成功爆零心态有点爆炸,不过至少知道了不能信大样例,唉。

    第一题?30分树上莫队?可惜我不会啊啊啊啊!
    试了试数据生成器?数据随机?

    发现数据生成的树由一条长链构成其余随机,那么可以在长链上主席树,其余暴力。。。

    由于day1 教训我查了好久T1。。
    然后整场比赛都在想T1啊。。。

    期望得分30 实际。。30 至少没有把暴力打挂很感动了。。
    总结:其实这场比赛最简单的题是t3 以后比赛前要通读题目啊

附t1代码

#include<cstdio>
#include<iostream>
#include<cmath>
#include<algorithm>
#include<cstring>
#include<set>
#define double  long double
using namespace std;
const double eps = 1e-13;
const double pi= acos(-1);
double curx;
struct node{
	double x,y,xx,yy;
}lin[1000010] , model;
struct straight{
	double a,b,c;
}lne;
struct node2{
	double x,y,k,xx,yy;
}nw1[1000010],nw2[1000010];
int t,n;
double l;
struct point
{
	int id,belong;
	double x,y;
}pt1[100100],pt2[100010];
struct line1{
	point aa,bb;
	double jieju,xielv;
	inline bool operator < (const line1 &p) const
	{
		return (jieju+xielv*curx)<(p.jieju+p.xielv*curx);
	}
}le1[1000010],le2[1000010];
void get(node x)
{
	if(fabs(x.x-x.xx)<eps)
	{
		lne.a=1;
		lne.b=0;
		lne.c=-x.x;
		return ;
	}
	if(fabs(x.yy-x.y)<eps)
	{
		lne.a=0;
		lne.b=1;
		lne.c=-x.y;
		return ;
	}
	double a=(x.y-x.yy)/(x.x-x.xx);
	double b=-1;
	double c=x.y-(x.y-x.yy)/(x.x-x.xx)*x.x;
	lne.a=a;
	lne.b=b;
	lne.c=c;
}
int getwhere(double x,double y)
{
	double tmp=lne.a*x+lne.c;
	if(tmp>y) return 1;
	else return 2;
}
bool cmp(node2 p,node2 q)
{
	return p.x<q.x;
}
double ans=0,ret=0;
bool cmpp(point p,point q)
{
	return p.x<q.x;
}
struct xianduan{
	double x,xx,k;
}ed1[500100],ed2[500010];
bool cmppp(xianduan p,xianduan q)
{
	if(p.x==q.x)
	return p.xx<q.xx;
	else return  p.x<q.x;
}
double sum[500010],summ[500010];
double work(int cnt1,int cnt2)
{
	for(register int i=1;i<=cnt1;++i) sum[i]=0;
	for(register int i=1;i<=cnt2;++i) summ[i]=0;
	double ret=0;
	ans=0;
	int ll=0,rr=0,ul=0,ur=0;
	for(register int i=1;i<=cnt1;++i)
	{
		double tmp=ed1[i].xx-ed1[i].x;
		double tmpp=tmp*ed1[i].k;
		sum[i]=sqrt(tmp*tmp+tmpp*tmpp);
		sum[i]+=sum[i-1];
	//	printf("%Lf %Lf %Lf %Lf\n",ed1[i].x,ed1[i].xx,ed1[i].k,sum[i]);
	}
	for(register int i=1;i<=cnt2;++i)
	{
		double tmp=ed2[i].xx-ed2[i].x;
		double tmpp=tmp*ed2[i].k;
		summ[i]=sqrt(tmp*tmp+tmpp*tmpp);
		summ[i]+=summ[i-1];
	//	printf("%Lf %Lf %Lf %Lf\n",ed2[i].x,ed2[i].xx,ed2[i].k,summ[i]);
	}
	for(register int i=1;i<=cnt1;++i)
	{
		ret=0;
		double left=ed1[i].x,rt=ed1[i].x+l;
		ll=i;
		while((ed1[rr].xx<rt||!rr)&&rr<cnt1) rr++;
		ret+=(sum[rr-1]-sum[i-1]);
		double tmp=min(rt,ed1[rr].xx)-max(left,ed1[rr].x);
		if(tmp>eps)
		{
			double tmpp=tmp*ed1[rr].k;ret+=sqrt(tmp*tmp+tmpp*tmpp);
		} 
		while((ed2[ul].xx<left||!ul)&&ul<cnt2) ul++;
		while((ed2[ur].xx<rt||!ur)&&ur<cnt2) ur++;
		ret+=max(summ[ur-1]-summ[ul],(double)0.0);
		if(ur==ul)
		{
			double tmp=min(rt,ed2[ur].xx)-max(left,ed2[ur].x);
			if(tmp>eps)
			{
				double tmpp=tmp*ed2[ur].k;ret+=sqrt(tmp*tmp+tmpp*tmpp);
			}
			if(ret>ans) ans=ret;
		}
		else
		{
			double tmp=min(rt,ed2[ur].xx)-max(left,ed2[ur].x);
			if(tmp>eps)
			{
				double tmpp=tmp*ed2[ur].k;ret+=sqrt(tmp*tmp+tmpp*tmpp);
			}
			tmp=min(rt,ed2[ul].xx)-max(left,ed2[ul].x);
			if(tmp>eps)
			{
				double tmpp=tmp*ed2[ul].k;ret+=sqrt(tmp*tmp+tmpp*tmpp);
			}
			if(ret>ans) ans=ret;
		}
	}
	ul=ur=ll=rr=0;
	for(register int i=1;i<=cnt1;++i)
	{
		ret=0;
		double left=ed1[i].xx-l,rt=ed1[i].xx;
		while((ed1[ll].xx<left||!ll)&&ll<cnt1) ll++;
		rr=i;
		ret+=(sum[rr]-sum[ll]);
		double tmp=min(rt,ed1[ll].xx)-max(left,ed1[ll].x);
		if(tmp>eps)
		{
			double tmpp=tmp*ed1[ll].k;ret+=sqrt(tmp*tmp+tmpp*tmpp);
		} 
		while((ed2[ul].xx<left||!ul)&&ul<cnt2) ul++;
		while((ed2[ur].xx<rt||!ur)&&ur<cnt2) ur++;
		ret+=max(summ[ur-1]-summ[ul],(double)0);
		if(ur==ul)
		{
			double tmp=min(rt,ed2[ur].xx)-max(left,ed2[ur].x);
			if(tmp>eps)
			{
				double tmpp=tmp*ed2[ur].k;ret+=sqrt(tmp*tmp+tmpp*tmpp);
			}
			if(ret>ans) ans=ret;
		}
		else
		{
			double tmp=min(rt,ed2[ur].xx)-max(left,ed2[ur].x);
			if(tmp>eps)
			{
				double tmpp=tmp*ed2[ur].k;ret+=sqrt(tmp*tmp+tmpp*tmpp);
			}
			tmp=min(rt,ed2[ul].xx)-max(left,ed2[ul].x);
			if(tmp>eps)
			{
				double tmpp=tmp*ed2[ul].k;ret+=sqrt(tmp*tmp+tmpp*tmpp);
			}
			if(ret>ans) ans=ret;
		}
	}
	ul=ur=ll=rr=0;
	for(register int i=1;i<=cnt2;++i)
	{
		ret=0;
		double left=ed2[i].xx-l,rt=ed2[i].xx;
		while((ed2[ll].xx<left||!ll)&&ll<cnt2)ll++;
		rr=i;
		ret+=(summ[rr]-summ[ll]);
		double tmp=min(rt,ed2[ll].xx)-max(left,ed2[ll].x);
		if(tmp>eps)
		{
			double tmpp=tmp*ed2[ll].k;ret+=sqrt(tmp*tmp+tmpp*tmpp);
		} 
		while((ed1[ul].xx<left||!ul)&&ul<cnt1) ul++;
		while((ed1[ur].xx<rt||!ur)&&ur<cnt1) ur++;
		ret+=max(sum[ur-1]-sum[ul],(double)0);
		if(ur==ul)
		{
			double tmp=min(rt,ed1[ur].xx)-max(left,ed1[ur].x);
			if(tmp>eps)
			{
				double tmpp=tmp*ed1[ur].k;ret+=sqrt(tmp*tmp+tmpp*tmpp);
			}
			if(ret>ans) ans=ret;
		}
		else
		{
			double tmp=min(rt,ed1[ur].xx)-max(left,ed1[ur].x);
			if(tmp>eps)
			{
				double tmpp=tmp*ed1[ur].k;ret+=sqrt(tmp*tmp+tmpp*tmpp);
			}
			tmp=min(rt,ed1[ul].xx)-max(left,ed1[ul].x);
			if(tmp>eps)
			{
				double tmpp=tmp*ed1[ul].k;ret+=sqrt(tmp*tmp+tmpp*tmpp);
			}
			if(ret>ans) ans=ret;
		}
	}
	ul=ur=ll=rr=0;
	for(register int i=1;i<=cnt2;++i)
	{
		ret=0;
		double left=ed2[i].x,rt=ed2[i].x+l;
		ll=i;
		while((ed2[rr].xx<rt||!rr)&&rr<cnt2) rr++;
		ret+=(summ[rr-1]-summ[i-1]);
		double tmp=min(rt,ed2[rr].xx)-max(left,ed2[rr].x);
		if(tmp>eps)
		{
			double tmpp=tmp*ed2[rr].k;ret+=sqrt(tmp*tmp+tmpp*tmpp);
		} 
		while((ed1[ul].xx<left||!ul)&&ul<cnt1) ul++;
		while((ed1[ur].xx<rt||!ur)&&ur<cnt1) ur++;
	//	printf("%Lf %Lf %d %d %d %d\n",left,rt,ll,rr,ul,ur);
		ret+=max(sum[ur-1]-sum[ul],(double)0);
		if(ur==ul)
		{
			double tmp=min(rt,ed1[ur].xx)-max(left,ed1[ur].x);
			if(tmp>eps)
			{
				double tmpp=tmp*ed1[ur].k;ret+=sqrt(tmp*tmp+tmpp*tmpp);
			}
			if(ret>ans) ans=ret;
		}
		else
		{
			double tmp=min(rt,ed1[ur].xx)-max(left,ed1[ur].x);
			if(tmp>eps)
			{
				double tmpp=tmp*ed1[ur].k;ret+=sqrt(tmp*tmp+tmpp*tmpp);
			}
			tmp=min(rt,ed1[ul].xx)-max(left,ed1[ul].x);
			if(tmp>eps)
			{
				double tmpp=tmp*ed1[ul].k;ret+=sqrt(tmp*tmp+tmpp*tmpp);
			}
			if(ret>ans) ans=ret;
		}
	//	cout<<endl<<ret<<endl;
	}
}
inline int read()
{
	int w=1,s=0;
	char ch=getchar();
	while(!isdigit(ch))
	{
		if(ch=='-') w=-1;
		ch=getchar();
	}
	while(isdigit(ch))
	{
		s=s*10+ch-'0';
		ch=getchar();
	}
	return w*s;
}
int main(){
//	freopen("01.in","r",stdin);
//	freopen("laser.out","w",stdout);
	cin>>t;
	while(t--)
	{
		set< line1  > st;
		ans=0;
		curx=0;
		n=read();
		for(register int i=1;i<=n;++i)
		{
			int x,y;
			x=read(),y=read(); lin[i].x=x,lin[i].y=y;x=read(),y=read();lin[i].xx=x,lin[i].yy=y;
		}
		int x,y,xx,yy,ll;
		x=read();y=read();xx=read();yy=read();ll=read(); 
		model.x=x,model.y=y,model.xx=xx,model.yy=yy;l=ll;
		get(model);
		double degree;
		if(fabs(lne.a)>eps)
		degree=atan(lne.a);
		if(lne.a==0){
			degree=0;
		}
		if(lne.b==0)
		{
			degree=pi/2;
		}
		int cnt1=0,cnt2=0;
		for(register int i=1;i<=n;++i)
		{
			double tx=lin[i].x,ty=lin[i].y;
			double lx=lin[i].xx,ly=lin[i].yy;
			double a=lne.a,b=lne.b,c=lne.c;
			int op=getwhere(tx,ty);
			if(op==2)
			{
				cnt1++;
				nw1[cnt1].x=cos(degree)*tx+sin(degree)*ty;
				nw1[cnt1].y=abs(a*tx+b*ty+c)/sqrt(a*a+b*b);
				nw1[cnt1].xx=cos(degree)*lx+sin(degree)*ly;
				nw1[cnt1].yy=abs(a*lx+b*ly+c)/sqrt(a*a+b*b);
				nw1[cnt1].k=(nw1[cnt1].yy-nw1[cnt1].y)/(nw1[cnt1].xx-nw1[cnt1].x);
				if(nw1[cnt1].xx<nw1[cnt1].x) swap(nw1[cnt1].xx,nw1[cnt1].x),swap(nw1[cnt1].yy,nw1[cnt1].y);
				
			}
			if(op==1)
			{
				cnt2++;
				nw2[cnt2].x=cos(degree)*tx+sin(degree)*ty;
				nw2[cnt2].y=abs(a*tx+b*ty+c)/sqrt(a*a+b*b);
				nw2[cnt2].xx=cos(degree)*lx+sin(degree)*ly;
				nw2[cnt2].yy=abs(a*lx+b*ly+c)/sqrt(a*a+b*b);
				nw2[cnt2].k=(nw2[cnt2].yy-nw2[cnt2].y)/(nw2[cnt2].xx-nw2[cnt2].x);
				if(nw2[cnt2].xx<nw2[cnt2].x) swap(nw2[cnt2].xx,nw2[cnt2].x),swap(nw2[cnt2].yy,nw2[cnt2].y);
			}
		}
		int tot1=0,tot2=0;
		for(register int i=1;i<=cnt1;++i)
		{
			pt1[++tot1].x= nw1[i].x;pt1[tot1].y=nw1[i].y;pt1[tot1].id=1;pt1[tot1].belong=i;
			le1[i].aa=pt1[tot1];
			pt1[++tot1].x=nw1[i].xx;pt1[tot1].y=nw1[i].yy;pt1[tot1].id=-1;pt1[tot1].belong=i;
			le1[i].bb=pt1[tot1];
			le1[i].xielv=nw1[i].k;
			le1[i].jieju=(nw1[i].y-nw1[i].k*nw1[i].x);
		}
		for(register int i=1;i<=cnt2;++i)
		{
			pt2[++tot2].x= nw2[i].x;pt2[tot2].y=nw2[i].y;pt2[tot2].id=1;pt2[tot2].belong=i;
			le2[i].aa=pt2[tot2];
			pt2[++tot2].x=nw2[i].xx;pt2[tot2].y=nw2[i].yy;pt2[tot2].id=-1;pt2[tot2].belong=i;
			le2[i].bb=pt2[tot2];
			le2[i].xielv=nw2[i].k;
			le2[i].jieju=(nw2[i].y-nw2[i].k*nw2[i].x);
		}
		sort(pt1+1,pt1+tot1+1,cmpp);
		sort(pt2+1,pt2+tot2+1,cmpp);
		curx=pt1[1].x;
		cnt1=0;
		st.insert(le1[pt1[1].belong]);
		for(register int i=2;i<=tot1;++i)
		{
			int tmp=pt1[i].belong;
			if(pt1[i].id==1){
				if(!st.empty()){
					ed1[++cnt1].x=curx,ed1[cnt1].xx=pt1[i].x;line1 qaq=*st.begin();ed1[cnt1].k=qaq.xielv;
			}
			curx=pt1[i].x;st.insert(le1[tmp]);
			}
			if(pt1[i].id==-1)
			{
				if(!st.empty())
				{
					ed1[++cnt1].x=curx,ed1[cnt1].xx=pt1[i].x;line1 qaq=*st.begin();ed1[cnt1].k=qaq.xielv;
				}
				curx=pt1[i].x;
				st.erase(le1[tmp]);
			}
		}
		curx=pt2[1].x;
		cnt2=0;
		st.insert(le2[pt2[1].belong]);
		for(register int i=2;i<=tot2;++i)
		{
			int tmp=pt2[i].belong;
			if(pt2[i].id==1){if(!st.empty()){ed2[++cnt2].x=curx,ed2[cnt2].xx=pt2[i].x;line1 qaq=*st.begin();ed2[cnt2].k=qaq.xielv;};curx=pt2[i].x;st.insert(le2[tmp]);};
			if(pt2[i].id==-1)
			{
				if(!st.empty())
				{
					ed2[++cnt2].x=curx,ed2[cnt2].xx=pt2[i].x;line1 qaq=*st.begin();ed2[cnt2].k=qaq.xielv;
				}
				curx=pt2[i].x;
				st.erase(le2[tmp]);
			}
		}
		sort(ed1+1,ed1+cnt1+1,cmppp);
		sort(ed2+1,ed2+cnt2+1,cmppp);
		work(cnt1,cnt2);
		printf("%.15Lf\n",ans);
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/was__n/article/details/80376578
今日推荐