zoukankan      html  css  js  c++  java
  • [Luogu5042/UOJ #100][国家集训队互测2015]丢失的题面/ydc的题面

    题目链接:

    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;
    }
    
  • 相关阅读:
    向量期望与方差的关系
    向量范数的柯西不等式
    pandas sample函数
    latex 插入表格的网址
    寻找原根
    反射
    python库下载速度慢的解决
    anaconda3 修改python版本
    spark RDD的缓存和检查点不同使用场景和工作机制 -- (视频笔记)
    HTML一键打包APK解决误报毒问题
  • 原文地址:https://www.cnblogs.com/LanrTabe/p/10800973.html
Copyright © 2011-2022 走看看