1. 程式人生 > 其它 >NOIP模擬16

NOIP模擬16

期望得分:0+20+40=60
實際得分:10+20+50=80
全打的暴力
T1 ,不會做,亂搞,求的每組點和點,點和上下邊的距離的一半,然後操作一下把樣例騙過去,水了十分
正解:每條到終點的路徑不可避免地會經過連線,要求的最小距離的最大值,計算最小距離可以求出連線的最小生成樹,這樣的話計算每條由頂端到底端的路徑,對每條路徑取最大值,所有路徑的最大值上取最小值

T2,小資料搞個狀壓,特殊性質不會搞
正解:求極大上升序列,dp,f[i]表示最後一個選的 i,每次求 i 之前,其對應值小於 i 的 且遞增的 j 取最小值,這樣可以保證不相交且極大
把第二維 j 放在樹上維護上升序列就好了,複雜度我不會算,題解說是\(O(nlog^2n)\)

T3,直接一路上去找父親,並維護最小值,小資料沒問題,20pts,隨機資料跑5e5沒問題,20pts,然後估分40,沒想到有個500多的亂入大資料,,,
正解:維護下凸包和可持久化棧,知識點沒學,還不會

T1



#include<bits/stdc++.h>
using namespace std;
const int N=6002;
struct pot_{
	int x,y;
	friend bool operator<(pot_ a,pot_ b)
	{
		return a.x<b.x;
	}
}pot[N];
struct line{
	int u,v;
	double w;
	friend bool operator<(line a,line b)
	{
		return a.w<b.w;
	}
}edge[N*(N-1)/2+1];
struct qxxx{
	int v,next;
	double w;
}cc[2*N];
double ans=0x7fffffff;
int n,m,k,ed_n;
int f[N];
int first[N],cnt;
bool jud[N];
inline int read()
{
	int s=0;
	char ch=getchar();
	while(ch>'9'||ch<'0')
		ch=getchar();
	while(ch>='0'&&ch<='9')
	{
		s=(s<<1)+(s<<3)+(ch^48);
		ch=getchar();
	}
	return s;
}
void qxx(int u,int v,double w)
{
	cc[++cnt].v=v;
	cc[cnt].w=w;
	cc[cnt].next=first[u];
	first[u]=cnt;
	return;
}
int find(int x)
{
	if(f[x]==x)
		return x;
	return f[x]=find(f[x]);
}
void kruscal()
{
	sort(edge+1,edge+ed_n+1);
	for(int i=1;i<=ed_n;i++)
	{
		int x=find(edge[i].u);
		int y=find(edge[i].v);
		if(x!=y)
		{
			f[x]=y;
			qxx(edge[i].u,edge[i].v,edge[i].w);
			qxx(edge[i].v,edge[i].u,edge[i].w);
		}
	}
	return;
}
void dfs(int x,double w)
{
	jud[x]=1;
	int s=0;
	for(int i=first[x];i;i=cc[i].next)
		if(!jud[cc[i].v])
		{
			dfs(cc[i].v,max(cc[i].w,w));
			s++;
		}
	if(!s)
	{
		ans=min(ans,max(w,(double)pot[x].y/2));
		return;
	}
	return;
}
int main()
{
	n=read();
	m=read();
	k=read();
	for(int i=1;i<=k;i++)
	{
		pot[i].x=read();
		pot[i].y=read();
		f[i]=i;
	}
	f[0]=0;
	sort(pot+1,pot+k+1);
	for(int i=1;i<=k;i++)
	{
		int sl=min(i+300,k);
		for(int j=i+1;j<=sl;j++)
		{
			edge[++ed_n].u=i;
			edge[ed_n].v=j;
			edge[ed_n].w=sqrt(fabs(pot[i].x-pot[j].x)*fabs(pot[i].x-pot[j].x)+fabs(pot[i].y-pot[j].y)*fabs(pot[i].y-pot[j].y));
		}
	}
	for(int i=1;i<=k;i++)
	{
		edge[++ed_n].u=0;
		edge[ed_n].v=i;
		edge[ed_n].w=m-pot[i].y;
	}
	kruscal();
	dfs(0,0);
	printf("%.10lf",ans/2);
	return 0;
}

T2



#include<bits/stdc++.h>
using namespace std;
const int N=200011;
struct tree{
	int l,r;
	int sum;
	int key;
}tre[4*N];
int n;
int pot[N],c[N];
int rle[N];
int dp[N];
inline int read()
{
	int s=0;
	char ch=getchar();
	while(ch>'9'||ch<'0')
		ch=getchar();
	while(ch>='0'&&ch<='9')
	{
		s=(s<<1)+(s<<3)+(ch^48);
		ch=getchar();
	}
	return s;
}
void build(int i,int l,int r)
{
	tre[i].l=l;
	tre[i].r=r;
	if(l==r)
		return;
	int mid=(l+r)>>1;
	build(i<<1,l,mid);
	build(i<<1|1,mid+1,r);
	return;
}
void updata(int i)
{
	tre[i].key=max(tre[i<<1].key,tre[i<<1|1].key);
	return;
}
void insert(int i,int x,tree val)
{
	if(tre[i].l==tre[i].r)
	{
		tre[i].sum=val.sum;
		tre[i].key=val.key;
		return;
	}
	int mid=(tre[i].l+tre[i].r)>>1;
	if(mid>=x)
		insert(i<<1,x,val);
	else
		insert(i<<1|1,x,val);
	updata(i);
	return;
}
tree query(int i,int x,int lim)
{
	tree ans,ans1,ans2;
	ans.sum=0x7fffffff;
	ans.key=0;
	if(tre[i].l==tre[i].r)
		return tre[i];
	if(tre[i].r<=x)
	{
		if(tre[i].key<=lim)
			return ans;
		int mid=(tre[i].l+tre[i].r)>>1;
		if(tre[i<<1|1].key<=lim)
			return query(i<<1,x,lim);
		if(tre[i<<1].key<=lim||tre[i<<1].key<tre[i<<1|1].key)
			return query(i<<1|1,x,lim);
		ans1=query(i<<1|1,x,lim);
		if(ans1.key)
		{
			ans2=query(i<<1,x,ans1.key);
			ans.key=ans2.key;
			ans.sum=min(ans2.sum,ans1.sum);
			return ans;
		}
		else
			return query(i<<1,x,lim);
	}
	else
	{
		if(tre[i].key<=lim)
			return ans;
		int mid=(tre[i].l+tre[i].r)>>1;
		if(mid+1>x)
			return query(i<<1,x,lim);
		else
		{
			if(tre[i<<1].key<=lim)
				return query(i<<1|1,x,lim);
			if(tre[i<<1|1].key<=lim)
				return query(i<<1,x,lim);
			ans1=query(i<<1|1,x,lim);
			if(ans1.key)
			{
				ans2=query(i<<1,x,ans1.key);
				ans.key=max(ans1.key,ans2.key);
				ans.sum=min(ans2.sum,ans1.sum);
				return ans;
			}
			else
				return query(i<<1,x,lim);
		}
	}
	return ans;
}
int main()
{
	n=read();
	for(int i=1;i<=n;i++)
		rle[pot[i]=read()]=i;
	for(int i=1;i<=n;i++)
		c[i]=read();
	build(1,1,n);
	tree ans;
	ans.sum=c[1];
	ans.key=1;
	insert(1,pot[1],ans);
	dp[1]=c[1];
	for(int i=2;i<=n;i++)
	{
		ans=query(1,pot[i]-1,0);
		if(ans.sum<0x7fffffff)
			dp[i]=c[i]+ans.sum;
		else
			dp[i]=c[i];
		ans.key=i;
		ans.sum=dp[i];
		insert(1,pot[i],ans);
	}
	int lim=pot[n];
	dp[0]=dp[n];
	for(int i=n-1;i;i--)
		if(pot[i]>lim)
		{
			dp[0]=min(dp[0],dp[i]);
			lim=pot[i];
		}
	cout<<dp[0]<<endl;
	return 0;
}