死亡冲刺打了5题。
来口胡把!
A:
白色的max为min(k1,k2) + abs(k1-k2)/2,黑色同理。
B:
找到最左侧两个0和最右侧的两个1,比一比这俩的位置,如果0在左边就yes。
C:
最终ans的长相肯定为1 1 1 1 1 1 拉满 拉满
所以倒着枚举一发,记录向右和向上的步数,随时给ans做checkmin就好。
D:
令
a
=
x
∗
p
&
&
b
=
y
∗
p
&
&
g
c
d
(
x
,
y
)
=
=
1
a = x*p\ \ \&\&\ \ b = y*p\ \ \&\&\ \ gcd(x,y)==1
a=x∗p && b=y∗p && gcd(x,y)==1。
则转化为上面那个式子。
考虑枚举x的因数,对应算,则转化为,给定一个数字,要求把他分成俩数字,这俩数字gcd为1的方案数。
显然是
2
P
r
i
m
e
d
i
v
c
o
u
n
t
2^{Prime\ div\ count}
2Prime div count。
线筛一个mindiv,一个P_D_C就好。
注意筛到2e7,不然wa4
#include<bits/stdc++.h>
#define int long long
using namespace std;
int tar = 20000010;
int prime[5000010];
bool vis[20000020];
int midiv[20000020],pdivcnt[20000020];
long long pw[40];
int pcnt;
int T;
int c,d,x;
void shai() {
for(int i=2;i<=tar;++i) {
if(!vis[i])
prime[++pcnt] = i, midiv[i] = i, pdivcnt[i] = 1;
for(int j=1;i*prime[j] <= tar;++j) {
vis[i*prime[j]] = 1;
midiv[i*prime[j]] = prime[j];
if(prime[j] != midiv[i])
pdivcnt[i*prime[j]] = pdivcnt[i] + 1;
else
pdivcnt[i*prime[j]] = pdivcnt[i];
if(i%prime[j] == 0)
break;
}
}
}
signed main() {
shai();
pw[0] = 1;
for(int i=1;i<=30;++i)
pw[i] = 2 * pw[i-1];
cin>>T;
while(T--) {
scanf("%lld%lld%lld",&c,&d,&x);
long long ans = 0;
int lim = sqrt(x);
for(int i=1;i<=lim;++i) {
if(i * i == x)
break;
if(x % i != 0)
continue;
int val1 = x/i, val2 = x/(x/i);
if((val1+d) % c == 0)
ans += pw[pdivcnt[(val1+d)/c]];
if((val2+d) % c == 0)
ans += pw[pdivcnt[(val2+d)/c]];
}
if(lim * lim == x) {
int val = lim;
if((val + d) %c == 0)
ans += pw[pdivcnt[(val+d)/c]];
}
printf("%lld\n",ans);
}
return 0;
}
E题:
先想想不做子串怎么搞。
dp[pre][pos1][pos2]。
初始状态dp[0][0][0] = 1,答案在dp[mark!=0][len1][len2]处统计。
考虑俩串的所有的前缀两两组合:把统计答案的位置变为dp[mark!=0][i][j]
考虑起点不一定为1,1:dp[0][i][j]全部初始化为1.
记得搞掉其中一个串为空串时,多增加的答案。
#include<bits/stdc++.h>
using namespace std;
char s[1010],t[1010];
long long dp[27][1010][1010];
long long mod = 998244353;
long long ans = 0;
int n,m;
int main() {
scanf("%s",s+1);
scanf("%s",t+1);
n = strlen(s+1), m = strlen(t+1);
for(int i=0;i<=n;++i) {
for(int j=0;j<=m;++j) {
dp[0][i][j] = 1;
}
}
int plu1 = 0;
int plu2 = 0;
for(int i=1;i<=n;++i) {
int loc = i;
for(int j=i+1;j<=n;++j) {
if(s[j] == s[j-1])
break;
loc = j;
}
plu1+=loc-i+1;
}
for(int i=1;i<=m;++i) {
int loc = i;
for(int j=i+1;j<=m;++j) {
if(t[j] == t[j-1])
break;
loc = j;
}
plu2+=loc-i+1;
}
for(int i=0;i<=n;++i) {
for(int j=0;j<=m;++j) {
for(int k=0;k<27;++k) {
if(k==0) {
if(i!=n) {
dp[s[i+1]-'a'+1][i+1][j] += dp[k][i][j];
dp[s[i+1]-'a'+1][i+1][j] %= mod;
}
if(j!=m) {
dp[t[j+1]-'a'+1][i][j+1] += dp[k][i][j];
dp[t[j+1]-'a'+1][i][j+1] %= mod;
}
}
else {
if(i!=n && s[i+1] - 'a' + 1 != k) {
dp[s[i+1]-'a'+1][i+1][j] += dp[k][i][j];
dp[s[i+1]-'a'+1][i+1][j] %= mod;
}
if(j!=m && t[j+1] - 'a' + 1 != k) {
dp[t[j+1]-'a'+1][i][j+1] += dp[k][i][j];
dp[t[j+1]-'a'+1][i][j+1] %= mod;
}
}
}
}
}
for(int i=1;i<=n;++i) {
for(int j=1;j<=m;++j) {
for(int k=1;k<=26;++k)
ans += dp[k][i][j], ans%=mod;
}
}
ans = ans - plu1 * m;
ans = ans - plu2 * n;
ans%=mod, ans += mod, ans %= mod;
cout<<ans;
return 0;
}
F题可能会补