CSU 1810 Reverse

来源:互联网 发布:沙钢集团网络培训 编辑:程序博客网 时间:2024/05/20 09:11

Description

Bobo has a n digits decimal number D=d1 d2…dn (It may have leading zeros).
Let R(i,j) denotes number D with digits between the i-th position and j-th position reversed. That is, R(i,j)=d1…di-1 dj dj-1…di dj+1 dj+2…dn.
Bobo would like to find
modulo (109+7).

Input

The input contains at most 30 sets. For each set:
The first line contains an integer n (1≤n≤105).
The second line contains n digits d1 d2…dn (0≤di≤9).

Output

For each set, an integer denotes the result.

Sample Input

2123012100123456789

Sample Output

45369

733424314

对于这类问题,通常采用的是统计每个位置的答案来累加。

n位数,我们考虑每一位最后会是那个数字。

对于第i个位置来说,最后仍旧是a[i]的情况有多少种呢。

一是变换的区间没有包含i,那么这种情况有(i-1)*i/2+(n-i)*(n-i+1)/2种(左边和右边)

另一种是包含了i,但交换之后仍旧是i的,一定是以i为中心的,有min(i,n-i+1)种

然后考虑变换以后,第i个位置上是a[j]的情况。

对于j又要分为i的左右两侧讨论。

以左侧为例,

对于反转之后能让a[j]到i,那么显然i和j是反转区间的对称点。

反转区间的左右端点必然是从[j,i],[j-1,i+1]....

这样对于j来说,显然是有min(j,n-i+1),左右极限

这样对于j<=n-i+1的来说,答案就是a[j]*j,对于大于n-i+1的j来说答案是a[j]*(n-i+1)

所以相应的,统计一下前缀和即可。

#include<set>#include<map>#include<ctime>#include<cmath>#include<stack>#include<queue>#include<bitset>#include<cstdio>#include<string>#include<cstring>#include<iostream>#include<algorithm>#include<functional>#define rep(i,j,k) for (int i = j; i <= k; i++)#define per(i,j,k) for (int i = j; i >= k; i--)#define loop(i,j,k) for (int i = j;i != -1; i = k[i])#define lson x << 1, l, mid#define rson x << 1 | 1, mid + 1, r#define ff first#define ss second#define mp(i,j) make_pair(i,j)#define pb push_back#define pii pair<int,LL>#define in(x) scanf("%d", &x);using namespace std;typedef long long LL;const int low(int x) { return x&-x; }const double eps = 1e-9;const int INF = 0x7FFFFFFF;const int mod = 1e9 + 7;const int N = 2e5 + 10;int T, n;LL L[N], l[N], r[N], R[N], a[N];char s[N]; int main(){    while (scanf("%d", &n) != EOF)    {        scanf("%s", s + 1);        rep(i, 1, n) a[i] = s[i] - '0';        l[0] = L[0] = R[0] = r[0] = 0;        rep(i, 1, n)        {            l[i] = (l[i - 1] + a[i]) % mod;            L[i] = (L[i - 1] + a[i] * i) % mod;            r[i] = (r[i - 1] + a[n - i + 1]) % mod;            R[i] = (R[i - 1] + a[n - i + 1] * i) % mod;        }        LL ans = 0, res;        rep(i, 1, n)        {            res = a[i] * (1LL * (i - 1)*i / 2 + 1LL * (n - i)*(n - i + 1) / 2) % mod;            res += a[i] * min(i, n - i + 1) % mod;            if (i - 1 >= n - i + 1)            {                res += L[n - i + 1] % mod;                res += (l[i - 1] - l[n - i + 1])*(n - i + 1) % mod;            }            else            {                res += L[i - 1] % mod;            }            if (n - i >= i)            {                res += R[i] % mod;                res += (r[n - i] - r[i])*i % mod;            }            else            {                res += R[n - i];            }            ans = (ans * 10 + res) % mod;        }        printf("%lld\n", ans);    }    return 0;}


0 0