【做题记录】多校-dp
A. Multitest Generator
考虑一个长为 \(m(m\ge 2)\) 的序列 \(b\),我们显然可以令 \(b_1=1,b_2=m-2\) 来使它变成 multitest。于是我们只需要判断能否使用 \(0\) 次或 \(1\) 次操作使其变成 multitest。
首先考虑 \(0\) 次,也就是它本身就是个 multitest。设 \(f_i\) 表示 \(i\sim n\) 这段后缀中有多少个 test,若不合法则 \(f_i=0\),可以 DP 出来。于是 \(i\) 的答案为 \(0\) 的充要条件即为 \(a_i=f_{i+1}\)。
考虑 \(1\) 次。首先如果 \(f_{i+1}\ne0\),那么我们可以直接修改 \(a_i\) 来满足要求。而如果 \(f_{i+1}=0\),我们则希望通过一次修改将 \(i+1\sim n\) 这段后缀变成 \(a_i\) 个 test。考虑如果能变成 \(x\) 个 test,则一定可以变成 \(x-1\) 个 test,于是设 \(g_i\) 表示通过一次修改能使 \(i\sim n\) 最多变成多少个 test,则有:
也就是分别考虑是否修改 \(a_i\)。于是若 \(g_{i+1}\ge a_i\) 那么 \(i\) 的答案为 \(1\),否则答案为 \(2\)。
Code
#include<bits/stdc++.h>
#define ll long long
#define il inline
using namespace std;
namespace asbt{
const int maxn=3e5+5;
int T,n,a[maxn],f[maxn],hp[maxn],g[maxn];
il void solve(){
cin>>n;
for(int i=1;i<=n;i++){
cin>>a[i];
}
f[n+1]=hp[n+1]=g[n+1]=0;
for(int i=n;i;i--){
f[i]=i+a[i]==n?1:i+a[i]>n||!f[i+a[i]+1]?0:f[i+a[i]+1]+1;
hp[i]=max(hp[i+1],f[i]);
g[i]=max(i+a[i]>n?0:g[i+a[i]+1]+1,hp[i+1]+1);
}
for(int i=1;i<n;i++){
cout<<(a[i]==f[i+1]?0:f[i+1]||g[i+1]>=a[i]?1:2)<<' ';
}
cout<<'\n';
}
int main(){
ios::sync_with_stdio(0),cin.tie(0);
cin>>T;
while(T--){
solve();
}
return 0;
}
}
int main(){return asbt::main();}
B. Bitwise Slides
记 \(s_i\) 为前缀异或和数组。则对于每一时刻,都有三个数的异或和为 \(s_i\)。又因为有两个相等,所以必然有一个值为 \(s_i\)。
设 \(dp_{i,j}\) 表示进行完第 \(i\) 次操作后那两个相等的数值为 \(j\) 的方案数。于是有转移:
-
\(j=s_{i-1}\),\(dp_{i,j}\gets 3dp_{i-1,j}\)。
-
\(j=s_i\),\(\begin{cases}dp_{i,j}\gets dp_{i-1,j}\\dp_{i,s_{i-1}}\gets2dp_{i,j}\end{cases}\)。
-
\(else\),\(dp_{i,j}\gets dp_{i-1,j}\)。
发现每次 DP 值改变的只有 \(dp_{i,s_{i-1}}\)。用 map 维护即可。
Code
#include<bits/stdc++.h>
#define ll long long
#define il inline
#define pii pair<int,int>
#define fir first
#define sec second
using namespace std;
namespace asbt{
const int maxn=2e5+5,mod=1e9+7;
il int pls(int x,int y){
return x+y<mod?x+y:x+y-mod;
}
il void add(int &x,int y){
x=pls(x,y);
}
il int mns(int x,int y){
return x<y?x-y+mod:x-y;
}
il void sub(int &x,int y){
x=mns(x,y);
}
int T,n,a[maxn];
map<int,int> dp;
int main(){
ios::sync_with_stdio(0),cin.tie(0);
cin>>T;
while(T--){
cin>>n;
dp.clear();
dp[0]=1;
for(int i=1,x;i<=n;i++){
cin>>x;
a[i]=a[i-1]^x;
dp[a[i-1]]=(dp[a[i-1]]*3ll+dp[a[i]]*2ll)%mod;
}
int ans=0;
for(pii i:dp){
add(ans,i.sec);
}
cout<<ans<<'\n';
}
return 0;
}
}
int main(){return asbt::main();}
C. Cows and Cool Sequences
考虑题目约束的实质,设那一段连续数字的开头为 \(t\),于是有 \(ty+\frac{y(y-1)}{2}=x\),即 \(\frac{2x}{y}-y=2t-1\),也就是要求 \(\frac{2x}{y}-y\) 为奇数。
考虑将每个数 \(x\) 的所有因子 \(2\) 都拆出来,也就是 \(x=2^{v(x)}\times p(x)\),其中 \(p(x)\) 为 \(x\) 的最大的奇约数。于是我们的要求即为 \(2^{v(x)-v(y)+1}\times\frac{p(x)}{p(y)}-y\) 为奇数。首先有 \(p(y)|p(x)\),然后对 \(y\) 的奇偶性进行分类讨论:
-
\(y\) 为奇数,则要求 \(2^{v(x)-v(y)+1}\times\frac{p(x)}{p(y)}\) 为偶数,即 \(v(x)-v(y)+1>0\),也就是 \(v(x)>-1\),即 \(v(x)\) 任取。
-
\(y\) 为偶数,则要求 \(2^{v(x)-v(y)+1}\times\frac{p(x)}{p(y)}\) 为奇数,即 \(v(x)-v(y)+1=0\),即 \(v(y)=v(x)+1\)。
于是我们可以得出 \((x,y)\) 合法的充要结论:\(p(y)|p(x)\land[v(y)=0\lor v(y)=v(x)+1]\)。考虑 DP,设 \(f_i\) 表示考虑到 \(i\) 且没有修改 \(i\),\(1\sim i\) 合法的最小修改次数。于是有转移:
答案即为 \(\min_{i=1}^{n}\{f_i+n-i\}\)。
Code
#include<bits/stdc++.h>
#define int long long
#define il inline
using namespace std;
namespace asbt{
const int maxn=5e3+5,inf=1e9;
int n,a[maxn],b[maxn],f[maxn];
int main(){
ios::sync_with_stdio(0),cin.tie(0);
cin>>n;
for(int i=1;i<=n;i++){
cin>>a[i];
while(a[i]%2==0){
a[i]>>=1,b[i]++;
}
}
f[1]=0;
for(int i=2;i<=n;i++){
f[i]=inf;
for(int j=1;j<i;j++){
if(a[j]%a[i]==0&&b[i]<=b[j]+i-j){
f[i]=min(f[i],f[j]+i-j-1);
}
}
}
int ans=inf;
for(int i=1;i<=n;i++){
ans=min(ans,f[i]+n-i);
}
cout<<ans;
return 0;
}
}
signed main(){return asbt::main();}
/*
__----~~~~~~~~~~~------___
. . ~~//====...... __--~ ~~
-. \_|// |||\\ ~~~~~~::::... /~
___-==_ _-~o~ \/ ||| \\ _/~~-
__---~~~.==~||\=_ -_--~/_-~|- |\\ \\ _/~
_-~~ .=~ | \\-_ '-~7 /- / || \ /
.~ .~ | \\ -_ / /- / || \ /
/ ____ / | \\ ~-_/ /|- _/ .|| \ /
|~~ ~~|--~~~~--_ \ ~==-/ | \~--===~~ .\
' ~-| /| |-~\~~ __--~~
|-~~-_/ | | ~\_ _-~ /\
/ \ \__ \/~ \__
_--~ _/ | .-~~____--~-/ ~~==.
((->/~ '.|||' -_| ~~-/ , . _||
-_ ~\ ~~---l__i__i__i--~~_/
_-~-__ ~) \--______________--~~
//.-~~~-~_--~- |-------~~~~~~~~
//.-~~~--\
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
神兽保佑 永无BUG
◢◤
▅▇
◢▆◤
◢ ◢▇◤
◢▇▆▇▇
◥▇▆◤
——Just_do_it
*/

浙公网安备 33010602011771号