题目链接
题目大意
要你构造一个严格单调递增的数组$ 1leq a[i] leq n, 1leq n leq 1e6$
使得不存在任意三个数的异或和为0
即构造的数组不存在(a[i]igoplus a[i+1]igoplus a[i+2]=0)
题目思路
很明显是一个dp
设(dp[i])表示结尾元素为(i)的值的方案数
那么显然(dp[i]=sum_{j=1}^{j=r-1}dp[j]-dp[iigoplus j](iigoplus j<j))
主要就是要找到(iigoplus j<j)的情况
下面说结论
对于二进制下的 (i) ,如果第 (x) 位为 1,那么 (2^x)到(2^{x+1}-1) 之间的数都是(除了最高位的1除外)
其实就是(iigoplus j)的最高位必定是必定是x有的二进制1,而且不能是最高位
这个其实可以手动模拟出来
代码
#include<bits/stdc++.h>
using namespace std;
#define fi first
#define se second
typedef long long ll;
typedef pair<double,int> pdi;
const ll INF=0x3f3f3f3f3f3f3f3f;
const int maxn=1e6+5,mod=998244353;
int n;
ll dp[maxn];
ll pre[maxn];
int main(){
scanf("%d",&n);
for(int i=1;i<=n;i++){
dp[i]=pre[i-1]+1;
for(int j=0;j<=30;j++){
if(i&(1<<j)&&i>=(1<<(j+1))){
dp[i]-=pre[(1<<(j+1))-1]-pre[(1<<j)-1];
dp[i]=(dp[i]%mod+mod)%mod;
}
}
pre[i]=((pre[i-1]+dp[i])%mod+mod)%mod;
}
printf("%lld
",pre[n]);
return 0;
}