本场考试考的很撇,值得反思,暴露出很多问题,望及时的拨乱反正,改掉操之过急,心态不稳定的缺点
2021年10月8日模拟赛(保龄奇遇记)
太菜了
T1 话中有话
有些词是多义词。这就导致同一句话可能有多种解读,即话中有话。
何老板给你一个字符串 A A A,同时给你一个单词 B B B。单词有两种不同的含义。
何老板想知道,字符串 A A A有多少种不同的解读?
solution:
d
p
+
k
m
p
(
a
c
自
动
机
)
dp+kmp(ac自动机)
dp+kmp(ac自动机)
d
p
[
i
]
=
d
p
[
i
−
1
]
+
(
f
a
i
l
[
i
]
=
=
l
e
n
b
)
?
d
p
[
i
−
l
e
n
b
]
:
0
;
dp[i] = dp[i-1] + (fail[i]==lenb)?dp[i-lenb]:0;
dp[i]=dp[i−1]+(fail[i]==lenb)?dp[i−lenb]:0;
T2岛中有桥
有一个岛国,该国由个 n n n岛构成。该国政府想要在岛间建一些桥,把所有岛都连接起来。
何老板承包了该国的建桥工程。经过实地的测量,何老板发现,受地理条件的限制,有 m m m对岛间是不能建桥的。其余的岛两两间都可以建桥。这样可能没法让所有岛都连通起来,只能形成若干相互连通的岛团。 该国政府决定把连通的岛团都设置为一个省,但希望省的个数尽量少。何老板想知道,最少能形成多少个省?每个省管辖的岛有几个?
solution: b f s + 染 色 bfs+染色 bfs+染色
我们可以将未染色的点存储起来,然后依次取出其中的点,然后可以进行bfs.
时间复杂度的分析:连通块内节点的个数为k,那么k个节点会向所有不在连通块内的所有节点连边,L = k*(n-k);
- 当n = 200000,k = 1,剩下的节点在一个连通块中,所有最多进行两次bfs;
- 当n = 1000,k = 200,剩下的节点也不会太多.
总结:此题最重要的就是时间复杂度的分析,因为一开始看到此题都会觉得不太可做,所以时间复杂的分析显得尤为重要,这样才可以让我们选择合适且高效的方法解题,该选择暴力的时候要胆大而心细.
T3 书中有学:
何老板给你两个整数 a a a和 n n n,请你帮忙计算:
∑ x = 1 n ∑ y = 1 n g c d ( a x − 1 , a y − 1 ) \sum_{x=1}^{n}\sum_{y=1}^{n}{gcd(a^x-1,a^y-1)} ∑x=1n∑y=1ngcd(ax−1,ay−1)
我们来化简这个式子(假设x>y)
g
c
d
(
a
x
−
1
,
a
y
−
1
)
=
g
c
d
(
a
x
−
a
y
,
a
y
−
1
)
gcd(a^x-1,a^y-1) = gcd(a^x-a^y,a^y-1)
gcd(ax−1,ay−1)=gcd(ax−ay,ay−1)
=
g
c
d
(
a
y
∗
(
a
x
−
y
−
1
)
,
a
y
−
1
)
=
g
c
d
(
a
x
−
y
−
1
,
a
y
−
1
)
=gcd(a^y*(a^{x-y}-1),a^y-1) = gcd(a^{x-y}-1,a^y-1)
=gcd(ay∗(ax−y−1),ay−1)=gcd(ax−y−1,ay−1)
= a g c d ( x , y ) − 1 =a^{gcd(x,y)} - 1 =agcd(x,y)−1
- 于是我们将原方程转化为 ∑ x = 1 n ∑ y = 1 n a g c d ( x , y ) − 1 \sum_{x=1}^{n}\sum_{y=1}^{n}{a^{gcd(x,y)}-1} ∑x=1n∑y=1nagcd(x,y)−1
然后到这里我们可以用一个
n
l
n
n
nln{n}
nlnn的算法来得到70分.直接拿分走人(到本蒟蒻考试时的推进极限了)
- 更近一步 ∑ d = 1 n a d ∗ ∑ x = 1 n ∑ y = 1 n [ g c d ( x , y ) = d ] − n 2 \sum_{d=1}^{n}{a^d*\sum_{x=1}^{n}\sum_{y=1}^{n}{[gcd(x,y)=d]}} - n^2 ∑d=1nad∗∑x=1n∑y=1n[gcd(x,y)=d]−n2
= ∑ d = 1 n a d ∗ ∑ x = 1 ⌊ n / d ⌋ ∑ y = 1 ⌊ n / d ⌋ [ g c d ( x , y ) = 1 ] − n 2 =\sum_{d=1}^{n}{a^d*\sum_{x=1}^{\lfloor{n/d}\rfloor}\sum_{y=1}^{\lfloor{n/d}\rfloor}{[gcd(x,y)=1]}} - n^2 =∑d=1nad∗∑x=1⌊n/d⌋∑y=1⌊n/d⌋[gcd(x,y)=1]−n2
- 继续化简(欧拉函数)
本蒟蒻不太会只有直接看题解上的解析了后面的明天再推进吧 - 最后化简成 = ∑ d = 1 n a d ∗ 2 ∗ ∑ x = 1 ⌊ n / d ⌋ ϕ ( x ) − n 2 =\sum_{d=1}^{n}{a^d* 2*\sum_{x=1}^{\lfloor{n/d}\rfloor} {\phi(x) }} - n^2 =∑d=1nad∗2∗∑x=1⌊n/d⌋ϕ(x)−n2
solution: 欧 拉 筛 ( 求 欧 拉 函 数 ) + 整 数 分 块 + 等 比 数 列 求 前 缀 和 欧拉筛(求欧拉函数)+整数分块+等比数列求前缀和 欧拉筛(求欧拉函数)+整数分块+等比数列求前缀和
最后展示下代码
#pragma GCC optimize(3)
#pragma GCC optimize(2)
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const ll mo = 1e9+7;
const int N = 1e6+10;
ll a,n;
ll prime[N],phi[N],p[N],sum[N];
void init(){
int cnt = 0;
p[0] = p[1] = 1;
phi[1] = 1;
for(int i=2;i<N;i++){
if(!p[i]){
prime[++cnt] = i;
phi[i] = i-1;
}
for(int j=1;j<=cnt&&i*prime[j]<N;j++){
int t = i*prime[j];
p[t] = 1;
if(i%prime[j]==0){
phi[t] = phi[i]*prime[j];
break;
}
phi[t] = phi[i]*(prime[j]-1);
}
}
for(int i=1;i<N;i++)
sum[i] = (sum[i-1] + phi[i]) %mo;
}//筛法求欧拉函数,sum[]求取前缀
/*
我们来感性证明筛法求欧拉函数的正确性.
首先对于i,和质数p,t = p*i;
如果i与p互质,phi[t] = phi[i] * phi[p],意思是说所有的与i互质的数和与p互质的数,两两相乘也一定是与互质
如果不互质的,与i互质的数加上p的整数倍依然与i互质,也就与p互质
*/
ll quick_pow(ll x,ll cnt){
ll res = 1;
for(;cnt;cnt>>=1,x=x*x%mo)if(cnt&1)res = res*x%mo;
return res;
}
int main(){
init();int T;scanf("%d",&T);
while(T--){
scanf("%lld%lld",&a,&n);
if(a==1){puts("0");continue;}
ll inv = quick_pow(a-1,mo-2),
ans = (mo-n*n)%mo,pre = 0,num;
for(int l=1,r,cnt;l<=n;l=r+1){
cnt = n/l;
r = n/cnt;
num = inv*(quick_pow(a,r+1) - a)%mo;
ans = (ans + (sum[cnt]*2%mo-1)*(num-pre)%mo)%mo;
pre = num;
}
ans = ((ans%mo)+mo)%mo;
printf("%lld\n",ans);
}
return 0;
}
T4 山中有牛
何老板到喜马拉雅山区去旅行,他发现有 n n n个村庄分布在高山上,村庄编号到,通过 n − 1 n-1 n−1条长度相等的山路连接起来,山路可以双向行走,任意两个村庄都可相互到达。
i i i号村庄的海拔高度为 h i h{i} hi, 1 1 1号村庄海拔最高,离村庄越近的村庄海拔越高。即如果村庄 i i i到村庄 1 1 1的距离小于村庄 j j j到村庄 1 1 1的距离,那么有 h i > h j h{i} > h{j} hi>hj山里的居民大都会养牦牛,不同的牦牛适应海拔高度不同。比如,在 k k k号村庄诞生了一头牦牛,兽医对它进行了体检,得出的结论是该牦牛只能在海拔高度 [ a , b ] [a,b] [a,b]范围能生存。超过这个海拔范围就会有生命危险。
今天共诞生了 m m m头牦牛,已知每头牦牛所在的村庄和它能适应的海拔范围,何老板想知道,每头牦牛的活动范围有多大?即求出每头牦牛能够走到多少个村庄去。
solution:树上倍增 + d f s dfs dfs序 + 主席树
由题可得祖先的高度一定是高于子孙的,所以我们先将一头牛从其实村庄向上跳到他所能去的最高的村庄 u u u,然后我们就查询以u号节点为根的子树中有多少节点的高度是大于下限的,于是我们利用 d f s dfs dfs序的方式将树上区间转为序列,并建立一棵主席树方便查询.