题目链接:
最近有点颓。。然后就打算找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;
}