链接
题意:
给定整数 n ( 1 ≤ l e n ( n ) < 1 0 5 n(1 \leq len(n) < 10^5 n(1≤len(n)<105 ,其中 l e n ( n ) len(n) len(n)表示 n n n 的位数)) ,现在规定每一轮Vova可以从中取出一段连续的几位数字,剩余数字即为该轮得分.结果可以拥有前导 0 0 0 .特别的,如果Vova取出了所有数字,那么该轮得分为 0 0 0 .
现在请你求出所有不同取法得分之和对 1 0 9 + 7 10^9+7 109+7取模后的值.特别的,如果有多种不同取法得到了同样的数字,得分要计多次.
分析:
首先我们对第i位上的数进行分析,看看他能做出多少贡献:
他做出贡献的方式有两种(三种):
- 删除i位前面的数
- 删除i位后面的数
- 删除包含i位连续的一段数(删了不作出贡献)
那么我们分析删除i位前面的数做出的贡献: 首先肯定的是删除i位之前,i位的贡献是不变的,都是 s t r [ i ] ∗ 1 0 l e n − i + 1 str[i]*10^{len-i+1} str[i]∗10len−i+1然后我们只需要算计算多少次就行,就看前面那一段数删出区间有多少种?从前(i-1)个数种选出2个数当左右区间即可也就是(i-1)*i/2.
然后看删除i位后面的数做出的贡献:同删除i位前面的数分析,不同的是i位的贡献是变化的,我们发现他贡献是这样变化的1,20,300,4000…,因为每当他后面多一位就多了一种选择。
/// 欲戴皇冠,必承其重。
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<ll, ll> pii;
typedef unsigned long long ull;
#define x first
#define y second
#define PI acos(-1)
#define inf 0x3f3f3f3f
#define lowbit(x) ((-x)&x)
#define debug(x) cout << #x << ": " << x << endl;
const int MOD = 998244353;
const int mod = 1e9+7;
const int N = 5e5 + 10;
const int dx[] = {0, 1, -1, 0, 0, 0, 0};
const int dy[] = {0, 0, 0, 1, -1, 0, 0};
const int dz[] = {0, 0, 0, 0, 0, 1, -1};
int day[] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
ll n, m,p;
string str;
void solve()
{
cin>>str;
ll len=str.size();
str=" "+str;
ll ans=0;
ll sum=0;
p=1;
for(ll i=len;i>=1;i--){
ll now = (i-1)*i/2;
ans = (ans+p*(str[i]-'0')%mod*now%mod)%mod;///只删前面】
ans = (ans + sum * (str[i]-'0') % mod ) % mod;///只删后面
sum = (sum + (len-i+1) *p %mod) % mod;
p = p * 10 % mod;
}
printf("%lld\n",ans);
}
int main()
{
ll t = 1;
///scanf("%lld", &t);
while(t--)
{
solve();
}
return 0;
}


187

被折叠的 条评论
为什么被折叠?



