LKOJ20201126Contest
这场考试没有认真做,就最后二十分钟打了两个暴力,于是\(20pts\)垫底了。
貌似跟高二的一起考垫底也不是什么很丢脸的事_
下午我们初三内部考试的时候,我花时间改了一下上午的题(然而由于题太简单还是有人\(AK\)了,\(orz:xzy,fkq\))。
觉得上午的题还是有很多可以值得学习的地方,努力做做\(200+\)应该是没问题的。
\(T1.\quad walking\)
有巨佬一看题就说是\(kmp\),\(SA\),\(SAM\)……(不像我一看题就没思路)
这是\(T1\)啊,哪有那么复杂……
模式串长度不超过\(100\),轨迹串长度不超过\(1e6\),这明显的\(\Theta(nm)\)复杂度。
考虑开\(bool\)数组\(dp[i][j]\)表示模式串前\(i\)个和轨迹串前\(j\)个是否匹配。
转移显然。\(get:\)搜索状态多\(\rightarrow dp\)。注意细节。
考后改题代码:
#include<bits/stdc++.h>
using namespace std;
inline int read(){
int x=0,f=1;char c=getchar();
while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
while(c>='0'&&c<='9'){x=(x<<1)+(x<<3)+c-'0';c=getchar();}
return x*f;
}
const int maxn=1e6+10;
const int N=105;
int n,ls,lt;
bool dp[N][maxn];
char s[N],t[maxn];
int main(){
freopen("walking.in","r",stdin);
freopen("walking.out","w",stdout);
scanf("%s",s+1);
ls=strlen(s+1);
n=read();
for(int cs=1;cs<=n;cs++){
scanf("%s",t+1);
lt=strlen(t+1);
for(int i=0;i<=ls;i++)
for(int j=0;j<=lt;j++)
dp[i][j]=false;
dp[0][0]=true;
for(int i=0;i<ls;i++){
if(s[i+1]=='*'){
for(int j=0;j<=lt;j++)
if(dp[i][j]==true){
for(int k=j;k<=lt;k++)
dp[i+1][k]=true;
break;
}
}else if(s[i+1]=='?'){
for(int j=0;j<lt;j++)
if(dp[i][j]==true)dp[i+1][j+1]=true;
}else if(s[i+1]=='['){
int cnt=1,pos=i+2;
while(cnt&&pos<=ls){
if(s[pos]=='[')cnt++;
if(s[pos]==']')cnt--;
pos++;
}
for(int j=0;j<=lt;j++)
if(dp[i][j]==true){
dp[pos-1][j]=true;
dp[i+1][j]=true;
}
}else if(s[i+1]==']'){
for(int j=0;j<=lt;j++)
if(dp[i][j]==true)dp[i+1][j]=true;
}else{
for(int j=0;j<lt;j++)
if(dp[i][j]==true&&s[i+1]==t[j+1])
dp[i+1][j+1]=true;
}
}
for(int i=1;i<=lt;i++)
if(dp[ls][i]==true)printf("1");
else printf("0");
puts("");
}
return 0;
}
\(T2.\quad deconstruct\)
一道期望题,最令我头疼的期望题。
其实这道题菊花和链的部分分显然,这就有\(30pts\)了,但是后来没打。
\(note:\)由于期望与不相关的边的断边顺序无关,故只需考虑相关边即可。
菊花:答案为\(n-1\)。
链:记\(f_i\)为长度为\(i\)的链的答案,\(f_0=0\),有转移\(f_i=\frac{1}{i}\sum\limits_{j=0}^{i-1}(f_j+f_{i-j-1}+i-j)\),答案为\(f_{n-1}\)。
正解:考虑每一个节点\(x\)对其祖先\(y\)产生贡献的期望。
\(x\)对\(y\)产生贡献当且仅当在\(x\rightarrow y\)的路径上与\(y\)相连的边第一个被断,其期望为\(\frac{1}{dis_{x\rightarrow y}}\)
将其求和即得总期望:\(E=\sum\limits_{i=1}^n\sum\limits_{j=1}^{dep_i}\frac{1}{j}\),预处理前缀和,遍历全树即可。
考后改题代码:
#include<bits/stdc++.h>
using namespace std;
inline int read(){
int x=0,f=1;char c=getchar();
while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
while(c>='0'&&c<='9'){x=(x<<1)+(x<<3)+c-'0';c=getchar();}
return x*f;
}
const int maxn=2e6+10;
const int mod=1e9+7;
int n,dep[maxn],inv[maxn],ans;
int beg[maxn],nex[maxn],to[maxn],e;
inline void add(int x,int y){
e++;nex[e]=beg[x];
beg[x]=e;to[e]=y;
}
inline void dfs(int x,int fa){
dep[x]=dep[fa]+1;
ans=(ans+inv[dep[x]-1])%mod;
for(int i=beg[x];i;i=nex[i])
dfs(to[i],x);
}
int main(){
freopen("deconstruct.in","r",stdin);
freopen("deconstruct.out","w",stdout);
n=read();inv[1]=1;
for(int i=2;i<=n;i++)
inv[i]=1ll*(mod-mod/i)*inv[mod%i]%mod;
for(int i=2;i<=n;i++)
inv[i]=(inv[i]+inv[i-1])%mod;
int x;
for(int i=2;i<=n;i++){
x=read();
add(x,i);
}
dfs(1,1);
printf("%d\n",ans);
return 0;
}
\(T3.\quad stone\)(先咕着)
\(T4.\quad landmine\)(先咕着)
总结:往后的考试机会不多了,要把每一次考试当成正式考试对待。
该拿的每一分都要拿到,拿不到的想办法给我拿到(什么鬼)。
能拍的给我拍上,不要划水,不要划水,不要划水!!!