Hdu 5921 Binary Indexed Tree
2016-10-05 21:53
218 查看
题解链接
题意搬运:
用树状数组维护一个序列,在给区间 [l,r] 加上一个t的时候,要给 [1,r]加上 t,给 [1,l−1] 减去 t,两次操作后值真正发生变化的节点个数就是这一次区间修改的代价,现在要修改每一个[1,n]的子区间,求总代价对 109+7取模后的结果。
题解搬运
记cnti表示i的二进制表达式中1的个数,lcp(i,j)表示i和j的二进制表示的最长公共前缀(如果长度不同,右对齐之后在左边补0),那么就是求∑r=1n∑l=0r−1(cntl+cntr−2cntlcp(l,r))=12∑l=0n∑r=0n(cntl+cntr−2cntlcp(l,r))考虑逐位计算贡献,对于第i位,枚举两个数l和r,如果前i位都相同那么没有贡献,否则贡献是l和r在第i位的数之和,于是dp[i][0/1][0/1][0/1]表示已经考虑了最高i位,现在l和r的前缀是否相等以及各自是否等于n的前缀的方案数,计算贡献时要补上后缀,观察到l和r的后缀是相互独立的,只需考虑前缀是否等于n的前缀。
其实dp数组就是前i位是否开始统计,l和r是否卡到上界的状态
每次统计的时候,当前位的能产生的贡献次数就是后面能接的后缀的个数
题意搬运:
用树状数组维护一个序列,在给区间 [l,r] 加上一个t的时候,要给 [1,r]加上 t,给 [1,l−1] 减去 t,两次操作后值真正发生变化的节点个数就是这一次区间修改的代价,现在要修改每一个[1,n]的子区间,求总代价对 109+7取模后的结果。
题解搬运
记cnti表示i的二进制表达式中1的个数,lcp(i,j)表示i和j的二进制表示的最长公共前缀(如果长度不同,右对齐之后在左边补0),那么就是求∑r=1n∑l=0r−1(cntl+cntr−2cntlcp(l,r))=12∑l=0n∑r=0n(cntl+cntr−2cntlcp(l,r))考虑逐位计算贡献,对于第i位,枚举两个数l和r,如果前i位都相同那么没有贡献,否则贡献是l和r在第i位的数之和,于是dp[i][0/1][0/1][0/1]表示已经考虑了最高i位,现在l和r的前缀是否相等以及各自是否等于n的前缀的方案数,计算贡献时要补上后缀,观察到l和r的后缀是相互独立的,只需考虑前缀是否等于n的前缀。
其实dp数组就是前i位是否开始统计,l和r是否卡到上界的状态
每次统计的时候,当前位的能产生的贡献次数就是后面能接的后缀的个数
#include<bits/stdc++.h> using namespace std; const int maxn = 63,mod = 1e9+7; #define LL long long int inser(int *s,LL *v,LL x){ memset(s,0,sizeof(int)*maxn); int len = 0; while(x) s[len++] = x & 1, x >>= 1; v[0] = s[0]; for(int i=1;i<len;i++) v[i] = v[i-1]+((1ll*s[i])<<i); for(int i=0;i<len;i++) v[i] = (v[i] + 1) % mod; return len; } LL dp[maxn][2][2][2], lr[maxn]; int lrs[maxn]; LL tim(int pos,bool lnd,bool rnd){ if(pos < 0) return 1; LL full = (1ll << (pos+1)) % mod, ret = 1; if(lnd) (ret *= lr[pos]) %= mod; else (ret *= full) %= mod; if(rnd) (ret *= lr[pos]) %= mod; else (ret *= full) %= mod; return ret; } LL dfs(int pos,bool lbnd,bool rbnd,bool scnt){ if(pos < 0) return 0; LL & ndp = dp[pos][lbnd][rbnd][scnt]; if(ndp != -1) return ndp; int lb = lbnd ? lrs[pos] : 1, rb = rbnd ? lrs[pos] : 1; ndp = 0; for(int i=0;i<=lb;i++){ for(int j=0;j<=rb;j++){ (ndp += dfs(pos-1 ,lbnd && i == lb ,rbnd && j == rb ,scnt || (i != j)) ) %= mod; (ndp += (scnt||(i!=j))*(i+j) * tim(pos-1 ,lbnd && i == lb ,rbnd && j == rb) ) %= mod; } } return ndp; } LL cal(LL num){ memset(dp,-1,sizeof(dp)); int n = inser(lrs,lr,num); return dfs(n-1,true,true,false); } int main(){ int T,icase = 1; scanf("%d",&T); LL n; memset(dp,-1,sizeof(dp)); while(T-- && ~scanf("%lld",&n)){ LL rev = (mod + 1) / 2; LL ans = cal(n)* rev % mod; printf("Case #%d: %lld\n",icase++,ans); } return 0; }
相关文章推荐
- Hdu 5921 Binary Indexed Tree(长春数位dp)
- CCPC长春赛区K题 hdu 5921 Binary Indexed Tree
- Hdu-5921 Binary Indexed Tree(数位DP)
- hdu——1710——Binary Tree Traversals
- 已知树的前序和中序求后序 hdu 题目1710 Binary Tree Traversals
- HDU (1710)Binary Tree Traversals
- 树状数组(Binary Indexed Tree)
- POJ 2481 树状数组(Binary Indexed Tree)
- hdu 1710 binary tree traversals 二叉树遍历
- Hdu Binary Tree Traversals
- Hdu Binary Tree Traversals
- HDU-1710-Binary Tree Traversals
- Binary Indexed Tree
- hdu 1710 Binary Tree Traversals
- hdu-1710-Binary Tree Traversals
- HDU--1710 -- Binary Tree Traversals
- POJ 2352 树状数组(Binary Indexed Tree)
- 树状数组(Binary Indexed Tree)
- 树状数组(Binary Indexed Tree)
- Hdu--1710--Binary Tree Traversals