省选测试27

A. 奶酪

分析

对于一条边,我们把它割断之后,一定会分成两部分

一部分是完整的子树,(dfn) 序是连续的

可以用树形 (dp) 预处理出来

另一部分左右两边的 (dfn) 序都是连续的

分别维护 (dfn) 序的前缀后缀直径以及直径的两个端点

直接把前缀和后缀合并查询即可

代码

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<cmath>
#define rg register
inline int read(){
	rg int x=0,fh=1;
	rg char ch=getchar();
	while(ch<'0' || ch>'9'){
		if(ch=='-') fh=-1;
		ch=getchar();
	}
	while(ch>='0' && ch<='9'){
		x=(x<<1)+(x<<3)+(ch^48);
		ch=getchar();
	}
	return x*fh;
}
const int maxn=4e6+5;
const long long mod=2333333333333333LL;
int h[maxn],tot=1,n;
struct asd{
	int to,nxt,val;
}b[maxn<<1];
void ad(rg int aa,rg int bb,rg int cc){
	b[tot].to=bb;
	b[tot].nxt=h[aa];
	b[tot].val=cc;
	h[aa]=tot++;
}
int siz[maxn],dfn[maxn],dfnc,son[maxn],fa[maxn],dep[maxn],tp[maxn],rk[maxn];
long long dis[maxn],maxdis[maxn];
void dfs1(rg int now,rg int lat){
	fa[now]=lat;
	dep[now]=dep[lat]+1;
	siz[now]=1;
	for(rg int i=h[now];i!=-1;i=b[i].nxt){
		rg int u=b[i].to;
		if(u==lat) continue;
		dis[u]=dis[now]+b[i].val;
		dfs1(u,now);
		siz[now]+=siz[u];
		if(son[now]==0 || siz[u]>siz[son[now]]) son[now]=u;
	}
}
void dfs2(rg int now,rg int top){
	tp[now]=top;
	dfn[now]=++dfnc;
	rk[dfnc]=now;
	if(son[now]) dfs2(son[now],top);
	for(rg int i=h[now];i!=-1;i=b[i].nxt){
		rg int u=b[i].to;
		if(u==fa[now] || u==son[now]) continue;
		dfs2(u,u);
	}
}
int getlca(rg int xx,rg int yy){
	while(tp[xx]!=tp[yy]){
		if(dep[tp[xx]]<dep[tp[yy]]) std::swap(xx,yy);
		xx=fa[tp[xx]];
	}
	return dep[xx]<dep[yy]?xx:yy;
}
long long getdis(rg int xx,rg int yy){
	return dis[xx]+dis[yy]-2LL*dis[getlca(xx,yy)];
}
long long pre[maxn][4],suf[maxn][4];
long long js(rg int l,rg int r){
	if(l==1){
		return suf[r+1][3];
	} else if(r==n){
		return pre[l-1][3];
	} else {
		rg int aa=suf[r+1][1],bb=suf[r+1][2],cc=pre[l-1][1],dd=pre[l-1][2];
		rg long long tmp=std::max(suf[r+1][3],pre[l-1][3]);
		tmp=std::max(tmp,std::max(getdis(aa,cc),getdis(aa,dd)));
		tmp=std::max(tmp,std::max(getdis(bb,cc),getdis(bb,dd)));
		return tmp;
	}
}
long long f[maxn],ans;
void dp(rg int now,rg int lat){
	maxdis[now]=dis[now];
	rg long long tmp=0;
	for(rg int i=h[now];i!=-1;i=b[i].nxt){
		rg int u=b[i].to;
		if(u==lat) continue;
		dp(u,now);
		f[now]=std::max(f[now],f[u]);
		f[now]=std::max(f[now],tmp+maxdis[u]-dis[now]);
		tmp=std::max(tmp,maxdis[u]-dis[now]);
		maxdis[now]=std::max(maxdis[now],maxdis[u]);
	}
}
int main(){
	memset(h,-1,sizeof(h));
	n=read();
	rg int aa,bb,cc;
	rg long long tmp;
	for(rg int i=1;i<n;i++){
		aa=read(),bb=read(),cc=read();
		ad(aa,bb,cc),ad(bb,aa,cc);
	}
	dfs1(1,0),dfs2(1,1),dp(1,0);
	pre[1][1]=pre[1][2]=rk[1];
	for(rg int i=2;i<=n;i++){
		aa=pre[i-1][1],bb=pre[i-1][2],cc=rk[i];
		pre[i][1]=aa,pre[i][2]=bb,pre[i][3]=pre[i-1][3];
		tmp=getdis(aa,cc);
		if(tmp>pre[i][3]) pre[i][1]=aa,pre[i][2]=cc,pre[i][3]=tmp;
		tmp=getdis(bb,cc);
		if(tmp>pre[i][3]) pre[i][1]=bb,pre[i][2]=cc,pre[i][3]=tmp;
	}
	suf[n][1]=suf[n][2]=rk[n];
	for(rg int i=n-1;i>=1;i--){
		aa=suf[i+1][1],bb=suf[i+1][2],cc=rk[i];
		suf[i][1]=aa,suf[i][2]=bb,suf[i][3]=suf[i+1][3];
		tmp=getdis(aa,cc);
		if(tmp>suf[i][3]) suf[i][1]=aa,suf[i][2]=cc,suf[i][3]=tmp;
		tmp=getdis(bb,cc);
		if(tmp>suf[i][3]) suf[i][1]=bb,suf[i][2]=cc,suf[i][3]=tmp;
	}
	rg long long tmp1,tmp2;
	for(rg int i=1;i<n;i++){
		aa=b[i*2].to,bb=b[i*2-1].to;
		if(dfn[aa]>dfn[bb]) std::swap(aa,bb);
		tmp1=js(dfn[bb],dfn[bb]+siz[bb]-1);
		tmp2=f[bb];
		ans+=std::max(tmp1,tmp2)*23333LL%mod+std::min(tmp1,tmp2)*2333LL%mod+233LL*i*i%mod+23LL*i%mod+2LL;
		ans%=mod;
	}
	printf("%lld
",ans);
	return 0;
}

B. 走

分析

(f[i][j][k]) 为当前在点 (i)(a) 的子串已经匹配了 (j) 的长度,(b) 的子序列已经匹配了 (k) 的长度到达最终状态的期望步数

转移有环可以用高斯消元去解决

但是直接做复杂度是 ((nab)^3)

可以发现沿着边走 (k) 一定是单调不减的

所以枚举 (k) 这一维,只对前两维进行高斯消元

有的高斯消元的写法要判掉图不连通的情况

代码

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#define rg register
inline int read(){
	rg int x=0,fh=1;
	rg char ch=getchar();
	while(ch<'0' || ch>'9'){
		if(ch=='-') fh=-1;
		ch=getchar();
	}
	while(ch>='0' && ch<='9'){
		x=(x<<1)+(x<<3)+(ch^48);
		ch=getchar();
	}
	return x*fh;
}
const int maxn=305,mod=998244353;
inline int addmod(rg int now1,rg int now2){
	return now1+=now2,now1>=mod?now1-mod:now1;
}
inline int delmod(rg int now1,rg int now2){
	return now1-=now2,now1<0?now1+mod:now1;
}
inline int mulmod(rg long long now1,rg int now2){
	return now1*=now2,now1>=mod?now1%mod:now1;
}
inline int ksm(rg int ds,rg int zs){
	rg int nans=1;
	while(zs){
		if(zs&1) nans=mulmod(nans,ds);
		ds=mulmod(ds,ds);
		zs>>=1;
	}
	return nans;
}
int h[maxn],tot=1;
struct asd{
	int to,nxt,val; 
}b[maxn*maxn];
void ad(rg int aa,rg int bb,rg int cc){
	b[tot].to=bb;
	b[tot].nxt=h[aa];
	b[tot].val=cc;
	h[aa]=tot++;
}
int mp[maxn][maxn],dp[maxn][maxn][55],nxt[maxn][maxn],id[maxn][maxn],cnt,lena,lenb,n,m,ans[maxn],du[maxn];
char sa[maxn],sb[maxn];
void gsxy(){
	rg int now=1;
	for(rg int i=1;i<=cnt;i++){
		rg int jl=now,mmax=mp[now][i];
		for(rg int j=now+1;j<=cnt;j++){
			if(mp[j][i]>mmax){
				mmax=mp[j][i];
				jl=j;
			}
		}
		if(jl!=now) std::swap(mp[jl],mp[now]);
		if(mmax==0) continue;
		rg int ny=ksm(mp[now][i],mod-2);
		for(rg int j=i;j<=cnt+1;j++) mp[now][j]=mulmod(mp[now][j],ny);
		for(rg int j=now+1;j<=cnt;j++){
			rg int tmp=mp[j][i];
			for(rg int k=i;k<=cnt+1;k++){
				mp[j][k]=delmod(mp[j][k],mulmod(mp[now][k],tmp));
			}
		}
		now++;
	}
	ans[cnt]=mp[cnt][cnt+1];
	for(rg int i=cnt-1;i>=1;i--){
		ans[i]=mp[i][cnt+1];
		for(rg int j=i+1;j<=cnt;j++){
			ans[i]=delmod(ans[i],mulmod(mp[i][j],ans[j]));
		}
	}
}
bool vis[maxn];
void dfs(rg int now){
	vis[now]=1;
	for(rg int i=h[now];i!=-1;i=b[i].nxt){
		rg int u=b[i].to;
		if(vis[u]) continue;
		dfs(u);
	}
}
int main(){
	memset(h,-1,sizeof(h));
	rg int aa,bb;
	rg char ch;
	n=read(),m=read();
	for(rg int i=1;i<=m;i++){
		aa=read(),bb=read();
		du[aa]++;
		scanf(" %c",&ch);
		ad(aa,bb,ch-'a');
	}
	dfs(1);
	for(rg int i=1;i<=n;i++) du[i]=ksm(du[i],mod-2);
	scanf("%s%s",sa+1,sb+1);
	lena=strlen(sa+1),lenb=strlen(sb+1);
	nxt[0][sa[1]-'a']=1;
	for(rg int i=1;i<lena;i++){
		for(rg int j=0;j<26;j++){
			rg int k=i+1,jud=1;
			for(;k>=1;k--){
				jud=1;
				if(sa[k]-'a'!=j) continue;
				for(rg int o=k-1;o>=1;o--) if(sa[o]!=sa[i-(k-o)+1]) jud=0;
				if(jud) break;
			}
			nxt[i][j]=k;
		}
	}
	for(rg int o=lenb-1;o>=0;o--){
		cnt=0;
		for(rg int i=1;i<=n;i++){
			if(!vis[i]) continue;
			for(rg int j=0;j<lena;j++){
				id[i][j]=++cnt;
			}
		}
		for(rg int i=1;i<=cnt;i++){
			for(rg int j=1;j<=cnt;j++){
				mp[i][j]=0;
			}
			ans[i]=0,mp[i][cnt+1]=1,mp[i][i]=1;
		}
		for(rg int i=1;i<=n;i++){
			if(!vis[i]) continue;
			for(rg int j=h[i];j!=-1;j=b[j].nxt){
				rg int u=b[j].to,v=b[j].val;
				if(!vis[u]) continue;
				for(rg int k=0;k<lena;k++){
					if(nxt[k][v]!=lena){
						if(sb[o+1]==v+'a') mp[id[i][k]][cnt+1]=addmod(mp[id[i][k]][cnt+1],mulmod(dp[u][nxt[k][v]][o+1],du[i]));
						else mp[id[i][k]][id[u][nxt[k][v]]]=addmod(mp[id[i][k]][id[u][nxt[k][v]]],mod-du[i]);
					}
				}
			}
		}
		gsxy();
		for(rg int i=1;i<=n;i++){
			if(!vis[i]) continue;
			for(rg int j=0;j<lena;j++){
				dp[i][j][o]=ans[id[i][j]];
			}
		}
	}
	printf("%d
",dp[1][0][0]);
	return 0;
}

C. 机

分析

毒瘤提交答案题

记几个有用的结论

(1)、通过 ((p−1)^kmodp) 判断 (k) 的奇偶性

(2)、通过二进制拆分的方式,把难以实现的加法操作转化为常数的加减和相乘

(3)、一个二进制优化的 (gcd) 算法

(4)、在模意义下,加法可以通过离散对数转化为乘法

(5)、提答题常见套路,暴力打表

代码(77分)

子任务1

input 1
pow 2 A[1] 100000
output A[2]

子任务2

input 30001
mul 30002 0 0
label tql
if A[30002] A[30001] orz
add 30002 A[30002] 1
input A[30002]
if 1 1 tql
label orz
mul 30002 1 A[30001]
label mod
if A[30002] 0 sto
output A[A[30002]]
add 30002 A[30002] 10000120
if 1 1 mod
label sto

子任务3

input 20001
input 20002
mul 20003 0 0
mul 0 1 1
label tql
if A[20003] A[20001] orz
mul 20004 A[20003] 1
add 20003 A[20003] 1
input A[20003]
mul A[20003] A[A[20003]] A[A[20004]]
if 1 1 tql
label orz
mul 20003 0 0
label mod
if A[20003] A[20002] sto
add 20003 A[20003] 1
input 20004
input 20005
add 20004 A[20004] 10000120
pow 20004 A[A[20004]] 10000119
mul 20005 A[20004] A[A[20005]]
output A[20005]
if 1 1 mod 
label sto

子任务4

input 1
pow 1 10000120 A[1]
if A[1] 1 orz
if A[1] 10000120 sto
label orz
output 1
if 1 1 goodbye
label sto
output 0
if 1 1 goodbye
label goodbye

子任务5

input 10
mul 1 1 1 
mul 2 1 2
mul 4 1 1 
mul 5 1 2
mul 11 1 11

label tql
if A[10] 0 orz
pow 9 10000120 A[10]
add 11 A[11] 1
if A[9] 1 oushu
add A[11] A[A[11]] 1
add 10 A[10] 10000120
label oushu
mul 10 A[10] 5000061
if 1 1 tql
label orz

mul 10 0 0

label sto
if A[11] 11 goodbye
mul 10 A[10] 2
if A[A[11]] 0 notadd
add 10 A[10] 1
label notadd
add 11 A[11] 10000120
mul 10 A[A[10]] 1
if 1 1 sto
label goodbye

if A[10] 0 yes
output 0
if 1 1 return
label yes
output 1
label return

子任务6

input 1010
mul 1011 1 0

label tql
if A[1010] 0 orz
pow 1009 10000120 A[1010]
add 1011 A[1011] 1
if A[1009] 1 oushu
add A[1011] A[A[1011]] 1
add 1010 A[1010] 10000120
label oushu
mul 1010 A[1010] 5000061
if 1 1 tql
label orz

input 1010
mul 1011 1 0

label tqla
if A[1010] 0 orza
pow 1009 10000120 A[1010]
add 1011 A[1011] 1
if A[1009] 1 oushua
add A[1011] A[A[1011]] 1
add 1010 A[1010] 10000120
label oushua
mul 1010 A[1010] 5000061
if 1 1 tqla
label orza

mul 666 1 30
mul 100 0 0

label sto
if A[666] 0 goodbye
mul 100 A[100] 2
if A[A[666]] 0 notadd
if A[A[666]] 1 notaddd
add 100 A[100] 1
label notaddd
add 100 A[100] 1
label notadd
add 666 A[666] 10000120
if 1 1 sto
label goodbye

output A[100]

子任务7

子任务8

子任务9

input 1
if A[1] 1559 orz
if A[1] 1567 orz
if A[1] 1571 orz
if A[1] 1579 orz
if A[1] 1583 orz
if A[1] 1597 orz
if A[1] 1601 orz
if A[1] 1607 orz
if A[1] 1609 orz
if A[1] 1613 orz
if A[1] 1619 orz
if A[1] 1621 orz
if A[1] 1627 orz
if A[1] 1637 orz
if A[1] 1657 orz
if A[1] 1663 orz
if A[1] 1667 orz
if A[1] 1669 orz
if A[1] 1693 orz
if A[1] 1697 orz
if A[1] 1699 orz
if A[1] 1709 orz
if A[1] 1721 orz
if A[1] 1723 orz
if A[1] 1733 orz
if A[1] 1741 orz
if A[1] 1747 orz
if A[1] 1753 orz
if A[1] 1759 orz
if A[1] 1777 orz
if A[1] 1783 orz
if A[1] 1787 orz
if A[1] 1789 orz
if A[1] 1801 orz
if A[1] 1811 orz
if A[1] 1823 orz
if A[1] 1831 orz
if A[1] 1847 orz
if A[1] 1861 orz
if A[1] 1867 orz
if A[1] 1871 orz
if A[1] 1873 orz
if A[1] 1877 orz
if A[1] 1879 orz
if A[1] 1889 orz
if A[1] 1901 orz
if A[1] 1907 orz
if A[1] 1913 orz
if A[1] 1931 orz
if A[1] 1933 orz
if A[1] 1949 orz
if A[1] 1951 orz
if A[1] 1973 orz
if A[1] 1979 orz
if A[1] 1987 orz
if A[1] 1993 orz
if A[1] 1997 orz
if A[1] 1999 orz
if A[1] 2 orz
if A[1] 3 orz
if A[1] 5 orz
if A[1] 7 orz
if A[1] 11 orz
if A[1] 13 orz
if A[1] 17 orz
if A[1] 19 orz
if A[1] 23 orz
if A[1] 29 orz
if A[1] 31 orz
if A[1] 37 orz
if A[1] 41 orz
if A[1] 43 orz
if A[1] 47 orz
if A[1] 53 orz
if A[1] 59 orz
if A[1] 61 orz
if A[1] 67 orz
if A[1] 71 orz
if A[1] 73 orz
if A[1] 79 orz
if A[1] 83 orz
if A[1] 89 orz
if A[1] 97 orz
if A[1] 101 orz
if A[1] 103 orz
if A[1] 107 orz
if A[1] 109 orz
if A[1] 113 orz
if A[1] 127 orz
if A[1] 131 orz
if A[1] 137 orz
if A[1] 139 orz
if A[1] 149 orz
if A[1] 151 orz
if A[1] 157 orz
if A[1] 163 orz
if A[1] 167 orz
if A[1] 173 orz
if A[1] 179 orz
if A[1] 181 orz
if A[1] 191 orz
if A[1] 193 orz
if A[1] 197 orz
if A[1] 199 orz
if A[1] 211 orz
if A[1] 223 orz
if A[1] 227 orz
if A[1] 229 orz
if A[1] 233 orz
if A[1] 239 orz
if A[1] 241 orz
if A[1] 251 orz
if A[1] 257 orz
if A[1] 263 orz
if A[1] 269 orz
if A[1] 271 orz
if A[1] 277 orz
if A[1] 281 orz
if A[1] 283 orz
if A[1] 293 orz
if A[1] 307 orz
if A[1] 311 orz
if A[1] 313 orz
if A[1] 317 orz
if A[1] 331 orz
if A[1] 337 orz
if A[1] 347 orz
if A[1] 349 orz
if A[1] 353 orz
if A[1] 359 orz
if A[1] 367 orz
if A[1] 373 orz
if A[1] 379 orz
if A[1] 383 orz
if A[1] 389 orz
if A[1] 397 orz
if A[1] 401 orz
if A[1] 409 orz
if A[1] 419 orz
if A[1] 421 orz
if A[1] 431 orz
if A[1] 433 orz
if A[1] 439 orz
if A[1] 443 orz
if A[1] 449 orz
if A[1] 457 orz
if A[1] 461 orz
if A[1] 463 orz
if A[1] 467 orz
if A[1] 479 orz
if A[1] 487 orz
if A[1] 491 orz
if A[1] 499 orz
if A[1] 503 orz
if A[1] 509 orz
if A[1] 521 orz
if A[1] 523 orz
if A[1] 541 orz
if A[1] 547 orz
if A[1] 557 orz
if A[1] 563 orz
if A[1] 569 orz
if A[1] 571 orz
if A[1] 577 orz
if A[1] 587 orz
if A[1] 593 orz
if A[1] 599 orz
if A[1] 601 orz
if A[1] 607 orz
if A[1] 613 orz
if A[1] 617 orz
if A[1] 619 orz
if A[1] 631 orz
if A[1] 641 orz
if A[1] 643 orz
if A[1] 647 orz
if A[1] 653 orz
if A[1] 659 orz
if A[1] 661 orz
if A[1] 673 orz
if A[1] 677 orz
if A[1] 683 orz
if A[1] 691 orz
if A[1] 701 orz
if A[1] 709 orz
if A[1] 719 orz
if A[1] 727 orz
if A[1] 733 orz
if A[1] 739 orz
if A[1] 743 orz
if A[1] 751 orz
if A[1] 757 orz
if A[1] 761 orz
if A[1] 769 orz
if A[1] 773 orz
if A[1] 787 orz
if A[1] 797 orz
if A[1] 809 orz
if A[1] 811 orz
if A[1] 821 orz
if A[1] 823 orz
if A[1] 827 orz
if A[1] 829 orz
if A[1] 839 orz
if A[1] 853 orz
if A[1] 857 orz
if A[1] 859 orz
if A[1] 863 orz
if A[1] 877 orz
if A[1] 881 orz
if A[1] 883 orz
if A[1] 887 orz
if A[1] 907 orz
if A[1] 911 orz
if A[1] 919 orz
if A[1] 929 orz
if A[1] 937 orz
if A[1] 941 orz
if A[1] 947 orz
if A[1] 953 orz
if A[1] 967 orz
if A[1] 971 orz
if A[1] 977 orz
if A[1] 983 orz
if A[1] 991 orz
if A[1] 997 orz
if A[1] 1009 orz
if A[1] 1013 orz
if A[1] 1019 orz
if A[1] 1021 orz
if A[1] 1031 orz
if A[1] 1033 orz
if A[1] 1039 orz
if A[1] 1049 orz
if A[1] 1051 orz
if A[1] 1061 orz
if A[1] 1063 orz
if A[1] 1069 orz
if A[1] 1087 orz
if A[1] 1091 orz
if A[1] 1093 orz
if A[1] 1097 orz
if A[1] 1103 orz
if A[1] 1109 orz
if A[1] 1117 orz
if A[1] 1123 orz
if A[1] 1129 orz
if A[1] 1151 orz
if A[1] 1153 orz
if A[1] 1163 orz
if A[1] 1171 orz
if A[1] 1181 orz
if A[1] 1187 orz
if A[1] 1193 orz
if A[1] 1201 orz
if A[1] 1213 orz
if A[1] 1217 orz
if A[1] 1223 orz
if A[1] 1229 orz
if A[1] 1231 orz
if A[1] 1237 orz
if A[1] 1249 orz
if A[1] 1259 orz
if A[1] 1277 orz
if A[1] 1279 orz
if A[1] 1283 orz
if A[1] 1289 orz
if A[1] 1291 orz
if A[1] 1297 orz
if A[1] 1301 orz
if A[1] 1303 orz
if A[1] 1307 orz
if A[1] 1319 orz
if A[1] 1321 orz
if A[1] 1327 orz
if A[1] 1361 orz
if A[1] 1367 orz
if A[1] 1373 orz
if A[1] 1381 orz
if A[1] 1399 orz
if A[1] 1409 orz
if A[1] 1423 orz
if A[1] 1427 orz
if A[1] 1429 orz
if A[1] 1433 orz
if A[1] 1439 orz
if A[1] 1447 orz
if A[1] 1451 orz
if A[1] 1453 orz
if A[1] 1459 orz
if A[1] 1471 orz
if A[1] 1481 orz
if A[1] 1483 orz
if A[1] 1487 orz
if A[1] 1489 orz
if A[1] 1493 orz
if A[1] 1499 orz
if A[1] 1511 orz
if A[1] 1523 orz
if A[1] 1531 orz
if A[1] 1543 orz
if A[1] 1549 orz
if A[1] 1553 orz
output 0
if 1 1 goodbye
label orz
output 1
label goodbye

子任务10

add 1 1 1
label bg
output A[1]
output A[1]
output A[1]
output A[1]
output A[1]
output A[1]
output A[1]
output A[1]
output A[1]
output A[1]
if A[A[1]] 1 out
add A[1] A[A[1]] 1
if 1 1 bg
label out
原文地址:https://www.cnblogs.com/liuchanglc/p/14433010.html