• 周五. 4月 26th, 2024

5G编程聚合网

5G时代下一个聚合的编程学习网

热门标签

[Luogu5042/UOJ #100][国家集训队互测2015]丢失的题面/ydc的题面

admin

11月 28, 2021

题目链接:

Luogu5042

UOJ #100

最近有点颓。。然后就打算找Duliu做

然后就有了这篇题解。。(虽然基本上都是抄的


  • (Task1)

输入(22),输出为长度为(2^{22})(01)

观察字符串容易发现前(2^k)的字符串由前(2^{k-1})以及前(2^{k-1})取反组成。

简单模拟。

  • (Task2)

输入(33),输出为长度为(Fib_{33})(01)串。

那么可以猜到字符串构造方法和斐波那契数列相似。

发现第(1)个串为”0″,第二个为”1″,后面的第(i)个由(i-2)(i-1)个字符串拼成。

基础模拟(用std::string特别方便

  • (Task3)

输入(12),输出为长度为(3^{12}+11)的三进制串

经过观察发现,答案包含所有长度为(12)的三进制数,字典序最小

那么打一个搜索就可以了


  • (Task4)

输入(131072)(131073)个数,输出(262144)(262145)个数

容易想到多项式相乘(下标(0sim 131072)(131073)个数。

利用前几个数推出模数(104857601),可以FFT

同时发现答案有对称性,那么可以猜想答案是((x+1)^{262144})的系数,即(C_{262144}^i)

验证成立。

  • (Task5)

输入和上一题相反,容易联想到多项式开方。

答案同样具有对称性,但是利用((x+1)^{131072})计算答案发现奇数项答案不同

那么就可以猜到答案应该是((x-1)^{131072})

  • (Task6)

输入和上面类似,但是这个是多项式开立方

类比上面,猜测答案是((ax+b)^{177147})

对几个特殊项联立方程,暴力求解,得(a=23333333,b=33333333)

(这个答案。。。


  • (Task7)

输入格式为典型的图论题格式,点数/边数/询问数/所有边信息/所有询问

发现答案只有(2)个:(0/0x7f7f7f7f)

那么可以猜到询问的答案只有(True/False)

显然询问点联通性,并查集水过。

  • (Task8)

同上,但是有边权,输入为一颗树

发现答案都偏大,猜测要求两点间边权最大值

求LCA同时维护边权最大值即可。

  • (Task9)

输入为一张图

答案要么偏大,要么(0x7f7f7f7f)

可以猜测是两点间所有路径边权最大值的最小值(不联通输出无穷大

那么先求最小生成树,在此基础上综合(Task7/8)即可。


  • (Task10)

无视奇怪的英文,直接输出答案即可(送分。

代码:(部分(Task)重合的地方一起利用

//Author:LanrTabe
//Language:C++
#pragma GCC optimize(3,"Ofast","inline")
#include <queue>
#include <cstdio>
#include <cctype>
#include <string>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
typedef long long ll;

//----------Input Optimize----------
char In[1<<20],*p1=In,*p2=In;
#define Getchar (p1==p2&&(p2=(p1=In)+fread(In,1,1<<20,stdin),p1==p2)?EOF:*p1++)
inline int Getint()
{
	register int x=0,c;
	while(!isdigit(c=getchar()));
	for(;isdigit(c);c=getchar())x=x*10+(c^48);
	return x;
}

//----------Output Optimize----------
char Out[1<<23],*Outp=Out,Cst[15],*Ctp=Cst;
inline void Putint(int x,const char c)
{
	do *Ctp++=x%10^48;
	while(x/=10);
	do *Outp++=*--Ctp;
	while(Ctp!=Cst);
	*Outp++=c;
}

//----------Other Optimize----------
inline int Min(const int a,const int b){return a<b?a:b;}
inline int Max(const int a,const int b){return a>b?a:b;}

int n,m,q;

namespace Task1
{
	void Maintain()
	{
		Out[0]='0';
		for(register int i=1;i<(1<<22);i<<=1)
			for(register int j=0;j<i;++j)
				Out[i+j]=Out[j]^1;
		fwrite(Out,1,1<<22,stdout),putchar('
');
	}
}

namespace Task2
{
	void Maintain()
	{
		std::string a="0",b="1",c;
		for(int i=3;i<=33;++i)c=a+b,a=b,b=c;
		for(register int i=0;i<(int)c.length();++i)*Outp++=c[i];
		*Outp++='
',fwrite(Out,1,Outp-Out,stdout);
	}
}

namespace Task3
{
	bool Vis[532000];

	bool DFS(int x,int y)
	{
		if(x==531441)return true;
		y=y*3%531441;
		for(int i=0;i<3;++i)
			if(!Vis[y+i])
			{
				Vis[y+i]=true,*Outp++=i^48;
				if(DFS(x+1,y+i))return true;
				Vis[y+i]=false,--Outp;
			}
		return false;
	}

	void Maintain()
	{
		for(int i=0;i<11;++i)*Outp++='0';
		DFS(0,0),*Outp++='
';
		fwrite(Out,1,Outp-Out,stdout);
	}
}

const int Mod=104857601;
int Fac[270005],Inv[270005];
#define C(n,m) ((ll)Fac[n]*Inv[m]%Mod*Inv[(n)-(m)]%Mod)

ll Pow(ll a,ll b)
{
	ll Res=1;
	for(;b;b>>=1,a=a*a%Mod)
		if(b&1)Res=Res*a%Mod;
	return Res%Mod;
}

void Prepare(const int Siz)
{
	for(register int i=Fac[0]=1;i<=Siz;++i)Fac[i]=(ll)Fac[i-1]*i%Mod;
	Inv[Siz]=Pow(Fac[Siz],Mod-2);
	for(register int i=Siz;i>=1;--i)Inv[i-1]=(ll)Inv[i]*i%Mod;
}

namespace Task4
{
	void Maintain()
	{
		Prepare(262144),Putint(262144,'
');
		for(register int i=0;i<=262144;++i)Putint(C(262144,i),'
');
		fwrite(Out,1,Outp-Out,stdout);
	}
}

namespace Task5
{
	void Maintain()
	{
		Prepare(131072),Putint(131072,'
');
		for(register int i=0;i<=131072;++i)
			Putint((C(131072,i)*((i&1)?-1:1)+Mod)%Mod,'
');
		fwrite(Out,1,Outp-Out,stdout);
	}
}

namespace Task6
{
	void Maintain()
	{
		Prepare(177147),Putint(177147,'
');
		for(register int i=0;i<=177147;++i)
			Putint(C(177147,i)*Pow(23333333,177147-i)%Mod*Pow(33333333,i)%Mod,'
');
		fwrite(Out,1,Outp-Out,stdout);
	}
}

int Fa[100005];
int Get(int x){return x==Fa[x]?x:Fa[x]=Get(Fa[x]);}

inline void PutFalse()
{
	*(Outp+0)='2',*(Outp+1)='1';
	*(Outp+2)='3',*(Outp+3)='9';
	*(Outp+4)='0',*(Outp+5)='6';
	*(Outp+6)='2',*(Outp+7)='1';
	*(Outp+8)='4',*(Outp+9)='3';
	Outp+=10;
}

namespace Task7
{
	void Maintain()
	{
		for(register int i=1;i<=n;++i)Fa[i]=i;
		for(q=Getint();m--;)Fa[Get(Getint())]=Get(Getint());
		for(;q--;*Outp++='
')
			if(Get(Getint())==Get(Getint()))*Outp++='0';
			else PutFalse();
		fwrite(Out,1,Outp-Out,stdout);
	}
}

int Head[100005],Next[200005],To[200005],Val[200005],En;
#define Add(x,y,z) (Next[++En]=Head[x],To[Head[x]=En]=y,Val[En]=z)
int Dep[100005],f[100005][16],g[100005][16];

void BFS(int St)
{
	std::queue<int> q;
	q.push(St),Dep[St]=1;
	for(register int x,y;!q.empty();q.pop())
		for(int i=Head[x=q.front()];i;i=Next[i])
			if(!Dep[y=To[i]])
			{
				Dep[y]=Dep[x]+1,q.push(y);
				f[y][0]=x,g[y][0]=Val[i];
				for(int j=1;j<=15;++j)
				{
					f[y][j]=f[f[y][j-1]][j-1];
					g[y][j]=Max(g[y][j-1],g[f[y][j-1]][j-1]);
				}
			}
}

int Query(int x,int y)
{
	int Res=0;
	if(Dep[x]<Dep[y])std::swap(x,y);
	for(int i=15;i>=0;--i)
		if(Dep[f[x][i]]>=Dep[y])
			Res=Max(Res,g[x][i]),x=f[x][i];
	if(x==y)return Res;
	for(int i=15;i>=0;--i)
		if(f[x][i]!=f[y][i])
		{
			Res=Max(Res,Max(g[x][i],g[y][i]));
			x=f[x][i],y=f[y][i];
		}
	return Max(Res,Max(g[x][0],g[y][0]));
}

namespace Task8
{
	void Maintain()
	{
		q=Getint();
		for(register int x,y,z;m--;Add(x,y,z),Add(y,x,z))
			x=Getint(),y=Getint(),z=Getint();
		BFS(1);
		for(register int x,y;q--;Putint(Query(x,y),'
'))
			x=Getint(),y=Getint();
		fwrite(Out,1,Outp-Out,stdout);
	}
}

namespace Task9
{
	struct Edge
	{
		int x,y,z;
		inline bool operator<(const Edge &o)const{return z<o.z;}
	}Es[100005];

	void Kruskal()
	{
		std::sort(Es+1,Es+m+1);
		for(register int i=1;i<=m;++i)
		{
			int Fx=Get(Es[i].x),Fy=Get(Es[i].y);
			if(Fx==Fy)continue;
			Fa[Fx]=Fy;
			Add(Es[i].x,Es[i].y,Es[i].z);
			Add(Es[i].y,Es[i].x,Es[i].z);
		}
	}

	void Maintain()
	{
		for(register int i=1;i<=n;++i)Fa[i]=i;
		m=Getint(),q=Getint();
		for(register int i=1;i<=m;++i)
			Es[i].x=Getint(),Es[i].y=Getint(),Es[i].z=Getint();
		Kruskal();
		for(register int i=1;i<=n;++i)
			if(!Dep[i])BFS(i);
		for(register int x,y;q--;)
		{
			x=Getint(),y=Getint();
			if(Get(x)!=Get(y))PutFalse(),*Outp++='
';
			else Putint(Query(x,y),'
');
		}
		fwrite(Out,1,Outp-Out,stdout);
	}
}

namespace Task10
{
	void Maintain()
	{
		puts("Your program should output itself here.");
		puts("Sounds very difficult, yeah?");
		puts("Anyway, good luck!");
	}
}

int main()
{
	n=Getint();
	if(n==22)Task1::Maintain();
	else if(n==33)Task2::Maintain();
	else if(n==12)Task3::Maintain();
	else if(n==131072)Task4::Maintain();
	else if(n==262144)Task5::Maintain();
	else if(n==531441)Task6::Maintain();
	else if(n==100000&&(m=Getint())==100000)Task7::Maintain();
	else if(m==99999)Task8::Maintain();
	else if(n==50000)Task9::Maintain();
	else if(n==100)Task10::Maintain();
	return 0;
}

《[Luogu5042/UOJ #100][国家集训队互测2015]丢失的题面/ydc的题面》有2个想法

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注