ABC154 EF题

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 }
View Code

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 }
View Code

猜你喜欢

转载自www.cnblogs.com/njwsf/p/12307419.html
154
EF
ABC
今日推荐