Codeforces 1422C題解

Couriersix發表於2020-10-05

題目

C. Bargain
time limit per test1 second
memory limit per test256 megabytes
inputstandard input
outputstandard output
Sometimes it is not easy to come to an agreement in a bargain. Right now Sasha and Vova can’t come to an agreement: Sasha names a price as high as possible, then Vova wants to remove as many digits from the price as possible. In more details, Sasha names some integer price n, Vova removes a non-empty substring of (consecutive) digits from the price, the remaining digits close the gap, and the resulting integer is the price.

For example, is Sasha names 1213121, Vova can remove the substring 1312, and the result is 121.

It is allowed for result to contain leading zeros. If Vova removes all digits, the price is considered to be 0.

Sasha wants to come up with some constraints so that Vova can’t just remove all digits, but he needs some arguments supporting the constraints. To start with, he wants to compute the sum of all possible resulting prices after Vova’s move.

Help Sasha to compute this sum. Since the answer can be very large, print it modulo 109+7.

Input
The first and only line contains a single integer n (1≤n<10105).

Output
In the only line print the required sum modulo 109+7.

Examples
inputCopy
107
outputCopy
42
inputCopy
100500100500
outputCopy
428101984
Note
Consider the first example.

Vova can choose to remove 1, 0, 7, 10, 07, or 107. The results are 07, 17, 10, 7, 1, 0. Their sum is 42.

思路

將這個數字分為三段,前m位,第x位和後n位,(m+n+1==string.length());,這樣總和就轉變為求後n位對第x位貢獻與前m位對第x位貢獻之和了。迴圈再求和一遍即可。
求後n位貢獻的方法,觀察可知,如果想讓第x位作為個位,(n=1)那麼後面只有0種選擇,所以貢獻和為1pow(10,0),如果想讓第x位作為十位(n=2),貢獻和為2pow(10,1);以此類推可知後n位的總貢獻和為tot+=i*fast(10,i-1)(1<=i<n);這裡fast是指快速冪。
求前m位貢獻的方法
這裡相當於在x位之前的高位刪除子序列,因此不影響後n位的貢獻和。因此列舉前m位刪除i個字元的情況,最後可得前面m位的貢獻和為(m+1)*m/2乘以後n位的貢獻和。

程式碼

#include<bits/stdc++.h>
#define ll long long
#define M 1000000007
using namespace std;
ll ans,len,tot[100005],t;
ll fast(ll a,ll b){
   ll ans,base;
   if (b==0) return 1%M;
   ans=1; base=a;
   while (b!=0){
   	     if (b & 1==1) ans=(ans*base)%M;
   	     base=base*base%M;
   	     b=b>>1;
   }
   return ans;
}
int main(){
	string s; ans=0;
	memset(tot,0,sizeof(tot));
	cin>>s; 
	len=s.length(); s='+'+s;
	for (int i=1; i<len; i++){
		 tot[i]=(tot[i-1]+(i*fast(10,i-1))%M)%M;  //第i位後面len-i項的貢獻和 
		// cout<<tot[i]<<endl;
	}
	for (ll i=1; i<=len; i++){
		t=s[i]-'0';
	    ans+=((t%M)*((((((i*(i-1))/2)%M)*fast(10,len-i))%M+tot[len-i])%M))%M;
	    ans%=M;
	}
	cout<<ans<<endl;
	return 0;
}

相關文章