E题:
题意:
给定一个小于1e100的数N,求有多少只有K位不为0,且小于等于N的数。
思路:
从高位开始,如果这一位不为0,那么考虑2种情况:
1.使符合要求的数这一位比N的这一位小,那么后面就可以随意填,只要保证大于0的位数有K个就行了,跳出。
2.使符合要求的数这一位等于N的这一位,那么后面依旧有限制,继续向下考虑(注意考虑不能超过K个大于1的位数)。
代码:
1 #pragma GCC optimize("Ofast,unroll-loops") 2 #include<bits/stdc++.h> 3 #define int long long 4 #define F first 5 #define S second 6 #define P pair 7 #define FOR(i,a,b) for(int i=a;i<=b;i++) 8 #define rep(i,a,b) for(int i=a;i<b;i++) 9 #define V vector 10 #define RE return 11 #define ALL(a) a.begin(),a.end() 12 #define MP make_pair 13 #define PB push_back 14 #define PF push_front 15 #define FILL(a,b) memset(a,b,sizeof(a)) 16 using namespace std; 17 string n;int k; 18 int check(int x,int y){ 19 if(x<y)RE 0; 20 int re=1; 21 FOR(i,1,y)re*=x-i+1; 22 FOR(i,2,y)re/=i; 23 FOR(i,1,y)re*=9; 24 RE re; 25 } 26 signed main(){ 27 ios::sync_with_stdio(0); 28 cin.tie(0); 29 cin>>n>>k; 30 int l=n.size(); 31 int ans=0; 32 rep(i,0,l){ 33 if(n[i]>'0'){ 34 ans=ans+check(l-i-1,k); 35 ans=ans+check(l-i-1,k-1)*(n[i]-'0'-1); 36 k--; 37 } 38 if(!k){ 39 ans++;break; 40 } 41 } 42 cout<<ans; 43 RE 0; 44 }
F题:
题意:
设f(r,c)表示在只能在x轴上移动1,或在y轴上移动1的情况下,从(0,0)到(r,c)有多少种路径。
给定r1,c1,r2,c2,求所有的f(i,j)(r1<=i<=r2)(c1<=j<=c2)的和。
思路:
可以把问题简化为给定l,r,求所有的f(i,j)(0<=i<=l)(0<=j<=r)的和,因为可以用二维前缀和的方式转换一下。
可以把矩阵分为从x轴开始的很多行,把矩阵看为x+1列y+1行。
第一行都只有1种,总数为x+1.
后面每一行都是在前一行的基础上增加,没多一行,就是多出一个在y轴上增加1.
考虑在前面的操作中加入这一操作,如果把x轴设为第0行,进行到第i行,上一行的操作平均有(x+i)个,可插入空隙有(x+i+1)个,还要去掉重复的,再除以(i+1)。
最后把每一行的答案都加起来,最后用二维前缀和算一下就行了。
代码:
1 #pragma GCC optimize("Ofast,unroll-loops") 2 #include<bits/stdc++.h> 3 #define int long long 4 #define F first 5 #define S second 6 #define P pair 7 #define FOR(i,a,b) for(int i=a;i<=b;i++) 8 #define rep(i,a,b) for(int i=a;i<b;i++) 9 #define V vector 10 #define RE return 11 #define ALL(a) a.begin(),a.end() 12 #define MP make_pair 13 #define PB push_back 14 #define PF push_front 15 #define FILL(a,b) memset(a,b,sizeof(a)) 16 using namespace std; 17 int inv[1000005],mod=1e9+7; 18 int c(int x,int y){ 19 int t=x+1,sum=t; 20 FOR(i,2,y+1){ 21 t=t*(x+i)%mod*inv[i]%mod; 22 sum=(sum+t)%mod; 23 } 24 RE sum; 25 } 26 signed main(){ 27 ios::sync_with_stdio(0); 28 cin.tie(0); 29 inv[1]=1; 30 FOR(i,2,1000001)inv[i]=mod-inv[mod%i]*(mod/i)%mod; 31 int c1,c2,r1,r2; 32 cin>>r1>>c1>>r2>>c2; 33 cout<<(c(c2,r2)-c(c1-1,r2)-c(c2,r1-1)+c(c1-1,r1-1)+2*mod)%mod; 34 RE 0; 35 }