[Luogu5042/UOJ #100][国家集训队互测2015]丢失的题面/ydc的题面
题目链接:
最近有点颓。。然后就打算找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\)个数
容易想到多项式相乘(下标\(0\sim 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('\n');
}
}
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++='\n',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++='\n';
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,'\n');
for(register int i=0;i<=262144;++i)Putint(C(262144,i),'\n');
fwrite(Out,1,Outp-Out,stdout);
}
}
namespace Task5
{
void Maintain()
{
Prepare(131072),Putint(131072,'\n');
for(register int i=0;i<=131072;++i)
Putint((C(131072,i)*((i&1)?-1:1)+Mod)%Mod,'\n');
fwrite(Out,1,Outp-Out,stdout);
}
}
namespace Task6
{
void Maintain()
{
Prepare(177147),Putint(177147,'\n');
for(register int i=0;i<=177147;++i)
Putint(C(177147,i)*Pow(23333333,177147-i)%Mod*Pow(33333333,i)%Mod,'\n');
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++='\n')
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),'\n'))
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++='\n';
else Putint(Query(x,y),'\n');
}
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;
}