【DP?】hihocoder1526 序列的值

题目描述

给定一个长度为 n 的序列 a[1..n],定义函数 f(b[1..m]) 的值为在 [0,m-1] 内满足如下条件的 i 的数目:

b 中前 i 个数异或起来的值小于 b 中前 i +1个数异或起来的值。

对于 a[1..n] 的每个子序列 b[1..m],求f(b[1..m])之和。


分析:

我们换一种思路:
设X为 ai 前的某些值的异或和,那么当: XX xor ai 时,就可以将i算入答案。
考虑二进制下 ai 中最高位的1,此时若那一位x为0,则一定满足条件,若那一位x为1,则一定不满足。所以我们仅通过 ai 中最高位那个1,就可以确定答案了。所以用 DP(i,j,k)(k=01) 表示前i个数中,任意组合进行异或,使得第j位为k的方案数。将这个方案数再乘以 2ni 即可(包涵此前缀的所有子序列均会计算)。

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#define SF scanf
#define PF printf
#define MAXN 100010
#define MOD 998244353
using namespace std;
long long dp[40][2],ans,bits[MAXN];
int n,x;
int main(){
    //freopen("data.in","r",stdin);
    //freopen("data.out","w",stdout);
    SF("%d",&n);
    int now=0;
    bits[0]=1ll;
    for(int i=1;i<=n;i++)
        bits[i]=(bits[i-1]<<1ll)%MOD;
    for(int i=0;i<31;i++)
        dp[i][0]=1;
    for(int i=0;i<n;i++){
        SF("%d",&x);
        int tag=0;
        int x1=x;
        if(x!=0){
            while(x!=1){
                x>>=1;
                tag++;
            }
            //PF("--{%d}--",n-i-1);
            //PF("[%lld (%d)]\n",dp[tag][0],tag);
            ans+=(1ll*dp[tag][0]*bits[n-i-1])%MOD;
            ans%=MOD;
        }
        for(int j=0;j<31;j++){
            if((x1&(1<<j))==0){
                dp[j][0]=(dp[j][0]+dp[j][0])%MOD;
                dp[j][1]=(dp[j][1]+dp[j][1])%MOD;

            }
            else{
                //PF("-[%d]-\n",j);
                long long x1=dp[j][0];
                long long x2=dp[j][1];
                dp[j][0]=(dp[j][0]+x2)%MOD;
                dp[j][1]=(dp[j][1]+x1)%MOD;
            }
        }
        //PF("[%d]",ans);
        now^=1;
    }
    PF("%lld",ans);
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值