Hdu 5921 Binary Indexed Tree(长春数位dp)
2016-11-07 20:30
489 查看
题意:用树状数组维护一个序列,在给区间[l,r]加上一个t的时候,要给[1,r]加上t,给[1,l−1]减去t,两次操作后值真正发生变化的节点个数就是这一次区间修改的代价,现在要修改每一个[1,n]的子区间,求总代价
对10^9+7取模后的结果。
对10^9+7取模后的结果。
#include<bits/stdc++.h> using namespace std; const int MOD=1e9+7; int dig[70]; long long C[70][70],Count[70],Pow[70],Left[70],Num[70],dp[70][3]; //Num[i]表示前面都有限制的情况下,后面i位可以获得的1的数目 //Left[i]表示二进制后面i位的值 //Count[i]表示前面没有限制的情况下,后面i位可以获得的1的数目 //dp[i]表示到了这一位没有限制 void add(long long &x,long long y){ x+=y; if(x>=MOD) x-=MOD; } //Pow[pos+1]*Count[pos+1]表示上面的方案数*下面总共选1的和 //Pow[pos+1]*Count[pos+1]表示下面的方案数*上面选一的和(不包含pre) //Pow[pos+1])*Pow[pos+1]表示pre这一位 long long dfs(int pos,int limit,int pre,int one_time){ if(pos==-1) return (pre==1&&one_time>1) ?1:0; long long ans=0; int time=one_time; if(time>2) time=2; if(!limit&&pre==1&&dp[pos][time]!=-1) return dp[pos][time]; if(!limit&&pre==1){ if(one_time==1) add(ans,(Pow[pos+1]*Count[pos+1]+(Pow[pos+1]-1)*Count[pos+1]+(Pow[pos+1]-1)*Pow[pos+1])%MOD);//这个数后面任意取 else add(ans,(Pow[pos+1]*Count[pos+1]+Pow[pos+1]*Count[pos+1]+(Pow[pos+1])*Pow[pos+1])%MOD);//这个数后面任意取 } else if(pre==1){ if(one_time==1) add(ans,((1+Left[pos])*Count[pos+1]+(Pow[pos+1]-1)*Num[pos]+ (Pow[pos+1]-1)*(1+Left[pos]))%MOD); else add(ans,((1+Left[pos])*Count[pos+1]+Pow[pos+1]*Num[pos]+Pow[pos+1]*(1+Left[pos]))%MOD); } int last=(limit==1 ? dig[pos]:1); for(int i=last;i>=0;i--) add(ans,dfs(pos-1,limit&(i==last),i,one_time+(i==1 ? 1:0))); if(!limit&&pre==1) dp[pos][time]=ans; return ans; } long long solve(long long num){ int len=0; while(num){ dig[len++]=num%2; num/=2; } for(int i=0;i<len;i++){ Left[i]=(Left[i-1]+dig[i]*Pow[i])%MOD; if(i!=0){ if(dig[i]==0) Num[i]=Num[i-1]; else Num[i]=(Num[i-1]+(Left[i-1]+1)+Count[i])%MOD; } else Num[i]=dig[i]; } return dfs(len-1,1,0,0)+Num[len-1]; } int main(){ int _; Pow[0]=1; for(int i=1;i<=64;i++) Pow[i]=Pow[i-1]*2%MOD; C[0][0]=C[1][0]=C[1][1]=1; for(int i=2;i<=64;i++) for(int j=0;j<=i;j++){ if(i==j) C[i][0]=C[i][j]=1; else C[i][j]=(C[i-1][j]+C[i-1][j-1])%MOD; } Count[0]=0; memset(dp,-1,sizeof(dp)); for(int i=1;i<=64;i++){ //有几个位置 Count[i]=0; for(int j=1;j<=i;j++)//放几个1 Count[i]=(Count[i]+C[i][j]*j)%MOD; } long long n; scanf("%d",&_); for(int Case=1;Case<=_;Case++){ scanf("%lld",&n); printf("Case #%d: %lld\n",Case,solve(n)%MOD); } return 0; }
相关文章推荐
- Hdu-5921 Binary Indexed Tree(数位DP)
- CCPC长春赛区K题 hdu 5921 Binary Indexed Tree
- Hdu 5921 Binary Indexed Tree
- 【hdu 6161】Big binary tree(二叉树、dp)
- HDU - 5534 Partial Tree(2015 ICPC 长春,感觉应该是一个早就应该会的简单DP技巧)
- HDU 6161 Big binary tree(树形DP)
- HDU 6161 Big binary tree(树形DP+map)
- hdu 5534 Partial Tree 2015长春区域赛 dp 脑洞
- HDU - 6161 Big binary tree(树上dp+hash优化空间)
- 2017 Multi-University Training Contest - Team 9 1001&&HDU 6161 Big binary tree【树形dp+hash】
- HDU 5534/ 2015长春区域H.Partial Tree DP
- HDU 5534 (ACM 2015 长春) Partial Tree [基础DP]
- HDU 3943 K-th Nya Number (数位DP)
- Binary Indexed Tree实现 国内称作 树状数组
- hdu 4359 Easy Tree DP?
- HDU_3709 Balanced Number 数位dp
- 树状数组(Fenwick tree,又名binary indexed tree
- hdu 4359 Easy Tree DP?
- hdu 3555 Bomb【数位DP】
- DP优化——四边形不等式 uva 10304 - Optimal Binary Search Tree