题解 AT1483 【1】

_虹_

2019-03-30 20:27:23

Solution

貌似没有递推的题解。 补上一篇。 ```cpp #include <iostream> #include <string> #include <vector> using namespace std; #define reg register const int kmaxn=25; typedef long long ll; ll dp[kmaxn][10];//dp(i,j)表示在第1-i位,第i位以1结尾,1到(i-1)位随便放时,1出现的次数 ll m[kmaxn]; int n; void init() { m[0]=dp[1][1]=1; m[1]=10; for(reg int i=2;i<=n;++i) { m[i]=m[i-1]*10;//预处理出10的i次幂 for(reg int j=0;j<10;++j) { for(reg int k=0;k<10;++k) { dp[i][j]+=dp[i-1][k];//不管这一位放什么,前一位都随便放,所以dp(i,j)=sigma dp(i,0 to 9); } } dp[i][1]+=m[i-1];//当这一位放1时贡献的答案 } } ll query(const vector<int>& vec) { ll res=0; ll ans=0; for(reg int i=0,j=vec.size();i<j;++i)//预处理出上界的数值 { res+=vec[i]*m[i]; } for(reg int i=vec.size();i>0;--i) { for(reg int j=0;j<vec[i-1];++j)//当前位小于上界,更高位==上界时 { ans+=dp[i][j]; } res-=vec[i-1]*m[i-1]; if(vec[i-1]==1)//当前位上界是一时,这个1产生的贡献就是低位的数值 ans+=res; } return ans; } inline void trans(vector<int>& vec,const string& str)//倒置整数+char转int { vec.clear(); for(reg int i=str.size()-1;i>=0;--i) { vec.push_back(str[i]-'0'); } } inline void add(vector<int>& vec)//加个一,闭区间变开区间 { int t=1; for(reg int i=0,j=vec.size();i<j;++i) { vec[i]+=t; t=vec[i]/10; vec[i]%=10; } if(t) vec.push_back(t); } string l,r; vector<int> lv,rv; int main() { ios::sync_with_stdio(false); cin>>r; n=r.size()+1; init(); trans(rv,r); add(rv); cout<<query(rv)<<endl; return 0; } 其实l和lv并没有用上的说,毕竟左边界是1,query(0)显然等于0... ```