传送门:CF1109
B.Sasha and One More Name
首先判断全部相同或是奇回文且只有 m i d mid mid不同的情况,无解。
如果是奇回文,至少都要切 2 2 2刀,且下界一定能达到。
如果是偶回文,不断把字符串长度 / 2 /2 /2(砍一半),直到出现奇回文或不回文子串:
若出现奇回文,还是至少切 2 2 2刀的情况,且下界一定能达到。
否则只用切一刀。
#include<bits/stdc++.h>
#define fl() puts("Impossible"),exit(0)
using namespace std;
const int N=5003;
int n;
char s[N];
int main(){
int i,j,mid;
scanf("%s",s+1);
n=strlen(s+1);mid=n>>1;
for(i=2;i<=mid && (s[i]==s[i-1]);++i);
if(i>mid) fl();
if(n&1) puts("2");
else{
for(;;mid>>=1){
for(i=1;mid-i+1>i && (s[i]==s[mid-i+1]);++i);
if((mid-i+1<=i) && (mid&1)) {
puts("2");break;}
else if(mid-i+1>i){
puts("1");break;}
}
}
return 0;
}
C.Sasha and a Patient Friend
大概可以把 l , r l,r l,r离散化之后套个 s e t + 线 段 树 set+线段树 set+线段树。
然而直接 B S T BST BST维护每次查询二分。
代码咕咕咕。
D.Sasha and Interesting Fact from Graph Theory
枚举 a , b a,b a,b链上的点数 k ( 0 ≤ k ≤ n − 2 ) k(0\leq k\leq n-2) k(0≤k≤n−2):
选出 k k k个点的方案 ( n − 2 ) ! ( n − 2 − k ) ! \dfrac{(n-2)!}{(n-2-k)!} (n−2−k)!(n−2)!,链上 k + 1 k+1 k+1条边边权方案 ( m − 1 k ) \dbinom{m-1}{k} (km−1),剩下 n − k − 2 n-k-2 n−k−2条边边权的方案 m n − k − 2 m^{n-k-2} mn−k−2。
关于怎么统计把剩下 n − 2 − k n-2-k n−2−k任意连向这条链的方案数,存在 Cayley’s formula \text{Cayley's formula} Cayley’s formula:
f ( n , k ) = k ⋅ n n − k − 1 f(n,k)=k·n^{n-k-1} f(n,k)=k⋅nn−k−1
即 n n n个点的森林 k k k个连通块,且 1 , 2 , . . . , k 1,2,...,k 1,2,...,k在不同连通块中的方案数。
数学归纳法证明-ymz
a n s = ∑ k = 0 n − 2 ( n − 2 ) ! ( n − 2 − k ) ! ( m − 1 k ) m n − k − 2 f ( n , k + 2 ) ( m o d 1 0 9 + 7 ) ans=\sum \limits_{k=0}^{n-2}\dfrac{(n-2)!}{(n-2-k)!}\dbinom{m-1}{k}m^{n-k-2}f(n,k+2) \pmod {10^9+7} ans=k=0∑n−2(n−2−k)!(n−2)!(km−1)mn−k−2f(n,k+2)(mod109