题解:CF2252E Generational Triplets
Eddie08012026 · · 题解
做本题摘去大脑,这是不需要任何观察和推导的做法。
准备
对以下两个条件数位 dp:
-
为满足等差数列限制
c=b+(b-a) -
为满足
a\oplus b\oplus c=0 ,a\oplus b=c
考虑
且
由于加减法列竖式是从低往高考虑,因此从低位向高位考虑。
考虑状态所需记录的条件,必要的是当前考虑到的位数
以及条件
这样判断
判断
则答案是
模拟即可。
Code
#include<bits/stdc++.h>
using namespace std;
using ll=long long;
const int mod=1e9+7;
ll n;
int t,f[65][2][2][2][2];
//前 i 位,是否借位,是否进位,[a!=b],[c<=n]
void sum(int &x,int y){
x=(x+y)%mod;
}
signed main(){
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
cin>>t;
while(t--){
cin>>n;
memset(f,0,sizeof(f));
f[0][0][0][0][1]=1;
for(int i=0;i<=__lg(n)+1;i++)for(int j=0;j<=1;j++)for(int k=0;k<=1;k++)for(int p=0;p<=1;p++)for(int q=0;q<=1;q++)for(int a=0;a<=1;a++)for(int b=0;b<=1;b++){
int J,K,P,Q;
int D=b-a-j;
J=(D<0);
int d=D&1;
int C=b+d+k;
K=(C>=2);
int c=C&1;
if(c!=(a^b))continue;
P=p|(a!=b);
int ni=(n>>i)&1;
if(c==ni)Q=q;
else Q=(c<ni);
sum(f[i+1][J][K][P][Q],f[i][j][k][p][q]);
}
cout<<f[__lg(n)+1][0][0][1][1]<<'\n';
}
return 0;
}