【DP?】hihocoder1526 序列的值
2018-01-16 15:08
232 查看
题目描述
给定一个长度为 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前的某些值的异或和,那么当:X<X xor ai时,就可以将i算入答案。
考虑二进制下ai中最高位的1,此时若那一位x为0,则一定满足条件,若那一位x为1,则一定不满足。所以我们仅通过ai中最高位那个1,就可以确定答案了。所以用DP(i,j,k)(k=0或1)表示前i个数中,任意组合进行异或,使得第j位为k的方案数。将这个方案数再乘以2n−i即可(包涵此前缀的所有子序列均会计算)。
#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); }
相关文章推荐
- 【HIHOCODER 1526】 序列的值(二进制DP)
- hihoCoder 1149 回文字符序列 (区间dp)
- [hihocoder1526]序列的值
- hihocoder 1149 : 回文字符序列(区间dp)
- hihocoder-1526 序列的值(DP/二进制)
- HDU 1231 最大连续子序列 (DP)
- [swust 1741] 最长递增子序列问题(DP,最大流)
- POJ 2250Compromise(DP最长子公共子序列)
- BZOJ 3675 APIO2014 序列分割 斜率优化DP
- Stacking Boxes +uva+dp(最长严格降子序列的变形)
- 区间DP(括号序列,uva1626)
- Is Bigger Smarter?+uva+简单dp(最长公共升降子序列的变形)
- hdu 1231 最大连续子序列 DP
- dp 括号序列
- HDU1025 最长上升子序列(nlogn算法) DP
- leetcode 446. Arithmetic Slices II - Subsequence 等差序列的数量 + 一个很值得学习的DP动态规划做法
- CodeForces 447C DZY Loves Sequences (dp 子序列)
- Codeforces 10D LCIS 找出最长公共子和产量增加这个序列 dp
- hrbust 哈理工OJ 2010 二等队形【dp】【最长递减子序列问题】
- nyoj 17 单调递增最长子序列(dp---记忆化搜索||穷举|| nlogn算法)