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:)搜索状态多( ightarrow 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}sumlimits_{j=0}^{i-1}(f_j+f_{i-j-1}+i-j)),答案为(f_{n-1})

正解:考虑每一个节点(x)对其祖先(y)产生贡献的期望。

(x)(y)产生贡献当且仅当在(x ightarrow y)的路径上与(y)相连的边第一个被断,其期望为(frac{1}{dis_{x ightarrow y}})

将其求和即得总期望:(E=sumlimits_{i=1}^nsumlimits_{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
",ans);
	return 0;
}

(T3.quad stone)(先咕着)

(T4.quad landmine)(先咕着)

总结:往后的考试机会不多了,要把每一次考试当成正式考试对待。

该拿的每一分都要拿到,拿不到的想办法给我拿到(什么鬼)。

能拍的给我拍上,不要划水,不要划水,不要划水!!!

原文地址:https://www.cnblogs.com/syzf2222/p/14044568.html