zoukankan      html  css  js  c++  java
  • C. Brave Seekers of Unicorns 题解(dp)

    题目链接

    题目大意

    要你构造一个严格单调递增的数组$ 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;
    }
    
    
    卷也卷不过,躺又躺不平
  • 相关阅读:
    JavaScript 闭包(转)
    JavaScript 获取键盘扫描码
    前台网站优化方案
    设计模式之装饰者模式
    设计模式之蝇量模式
    设计模式之策略模式
    Algorithm学习之any_of
    Algorithm学习之all_of学习
    Algorithm学习之adjacent_find学习
    数据结构-表达式求值
  • 原文地址:https://www.cnblogs.com/hunxuewangzi/p/14516099.html
Copyright © 2011-2022 走看看