CodeForces 1281 C. Cut and Paste

Description:

\quad We start with a string s consisting only of the digits 1 , 2 , 1, 2, 1,2, or 3 3 3. The length of s s s is denoted by ∣ s ∣ |s| s. For each i from 1 1 1 to ∣ s ∣ |s| s, the i-th character of s s s is denoted by s i . s_{i}. si.

\quad There is one cursor. The cursor’s location ℓ is denoted by an integer in {0,…,|s|}, with the following meaning:

  • If ℓ = 0 ℓ=0 =0, then the cursor is located before the first character of s s s.

  • If ℓ = ∣ s ∣ ℓ=|s| =s, then the cursor is located right after the last character of s s s.

  • If 0 < ℓ < ∣ s ∣ , 0<ℓ<|s|, 0<<s, then the cursor is located between sℓ and s ℓ + 1 sℓ+1 s+1.
    We denote by sleft the string to the left of the cursor and sright the string to the right of the cursor.

\quad We also have a string c c c, which we call our clipboard, which starts out as empty. There are three types of actions:

  • The Move action. Move the cursor one step to the right. This
    increments ℓ ℓ once.

  • The Cut action. Set c ← s r i g h t c←s_{right} csright, then set s ← s l e f t s←s_{left} ssleft.

  • The Paste action. Append the value of c to the end of the string s s s. Note that this doesn’t modify c c c.

The cursor initially starts at ℓ=0. Then, we perform the following procedure:

  • Perform the Move action once.

  • Perform the Cut action once.

  • Perform the Paste action sℓ times.
    If ℓ = x ℓ=x =x, stop. Otherwise, return to step 1 1 1.
    You’re given the initial string s and the integer x x x. What is the length of s s s when the procedure stops? Since this value may be very large, only find it modulo 109+7.

It is guaranteed that ℓ ≤ ∣ s ∣ ℓ≤|s| s at any time.

Input

The first line of input contains a a a single integer t ( 1 ≤ t ≤ 1000 ) t (1≤t≤1000) t(1t1000) denoting the number of test cases. The next lines contain descriptions of the test cases.

The first line of each test case contains a single integer x ( 1 ≤ x ≤ 1 0 6 ) x (1≤x≤10^6) x(1x106). The second line of each test case consists of the initial string s ( 1 ≤ ∣ s ∣ ≤ 500 ) s (1≤|s|≤500) s(1s500). It is guaranteed, that s s s consists of the characters " 1 " , " 2 " , " 3 " "1", "2", "3" "1","2","3".

It is guaranteed that the sum of x x x in a single file is at most 1 0 6 10^6 106. It is guaranteed that in each test case before the procedure will stop it will be true that ℓ ≤ ∣ s ∣ ℓ≤|s| s at any time.

Output

For each test case, output a single line containing a single integer denoting the answer for that test case modulo 1 0 9 + 7 10^9+7 109+7.

Example
input

4
5
231
7
2323
6
333
24
133321333

output

25
1438
1101
686531475

Note

Let’s illustrate what happens with the first test case. Initially, we have s= 231. Initially, ℓ=0 and c=ε (the empty string). The following things happen if we follow the procedure above:

  • Step 1, Move once: we get ℓ = 1 ℓ=1 =1.

  • Step 2, Cut once: we get s = 2 s= 2 s=2 and c = 31. c= 31. c=31.

  • Step 3, Paste s ℓ = 2 sℓ= 2 s=2 times: we get s = 23131 s= 23131 s=23131.

  • Step 4: ℓ = 1 ≠ x = 5 ℓ=1≠x=5 =1=x=5, so we return to step 1.

  • Step 1, Move once: we get ℓ = 2 ℓ=2 =2.

  • Step 2, Cut once: we get s = 23 s= 23 s=23 and c = 131 c= 131 c=131.

  • Step 3, Paste s ℓ = 3 sℓ= 3 s=3 times: we get s = 23131131131 s= 23131131131 s=23131131131.

  • Step 4: ℓ = 2 ≠ x = 5 ℓ=2≠x=5 =2=x=5, so we return to step 1 1 1.

  • Step 1, Move once: we get ℓ = 3 ℓ=3 =3.

  • Step 2, Cut once: we get s = 231 s= 231 s=231 and c = 31131131 c= 31131131 c=31131131.

  • Step 3, Paste s ℓ = 1 sℓ= 1 s=1 time: we get s = 23131131131 s= 23131131131 s=23131131131.

  • Step 4: ℓ = 3 ≠ x = 5 ℓ=3≠x=5 =3=x=5, so we return to step 1.

  • Step 1, Move once: we get ℓ = 4 ℓ=4 =4.

  • Step 2, Cut once: we get s = 2313 s= 2313 s=2313 and c = 1131131 c= 1131131 c=1131131.

  • Step 3, Paste s ℓ = 3 sℓ= 3 s=3 times: we get s = 2313113113111311311131131 s= 2313113113111311311131131 s=2313113113111311311131131.

  • Step 4: ℓ = 4 ≠ x = 5 ℓ=4≠x=5 =4=x=5, so we return to step 1.

  • Step 1, Move once: we get ℓ = 5 ℓ=5 =5.

  • Step 2, Cut once: we get s = 23131 s= 23131 s=23131 and c = 13113111311311131131 c= 13113111311311131131 c=13113111311311131131.

  • Step 3, Paste s ℓ = 1 sℓ= 1 s=1 times: we get s = 2313113113111311311131131 s= 2313113113111311311131131 s=2313113113111311311131131.

  • Step 4: ℓ = 5 = x ℓ=5=x =5=x, so we stop.
    At the end of the procedure, s has length 25 25 25.

题意: 每次分割字符串,把后面的乘以此时分割点的倍数加到后面,然后问x次操作串能到多长。 这道题我当时考虑了一下只有把原本字符串长度步数内操作完加上的字符串就够用的了,但是自己否定自己了,没敢写,所以掉分了。

AC代码:

#include <cstdio>
#include <vector>
#include <queue>
#include <cstring>
#include <cmath>
#include <map>
#include <set>
#include <string>
#include <iostream>
#include <algorithm>
#include <iomanip>
#include <stack>
#include <queue>
using namespace std;
#define sd(n) scanf("%d", &n)
#define sdd(n, m) scanf("%d%d", &n, &m)
#define sddd(n, m, k) scanf("%d%d%d", &n, &m, &k)
#define pd(n) printf("%d\n", n)
#define pc(n) printf("%c", n)
#define pdd(n, m) printf("%d %d", n, m)
#define pld(n) printf("%lld\n", n)
#define pldd(n, m) printf("%lld %lld\n", n, m)
#define sld(n) scanf("%lld", &n)
#define sldd(n, m) scanf("%lld%lld", &n, &m)
#define slddd(n, m, k) scanf("%lld%lld%lld", &n, &m, &k)
#define sf(n) scanf("%lf", &n)
#define sc(n) scanf("%c", &n)
#define sff(n, m) scanf("%lf%lf", &n, &m)
#define sfff(n, m, k) scanf("%lf%lf%lf", &n, &m, &k)
#define ss(str) scanf("%s", str)
#define rep(i, a, n) for (int i = a; i <= n; i++)
#define per(i, a, n) for (int i = n; i >= a; i--)
#define mem(a, n) memset(a, n, sizeof(a))
#define debug(x) cout << #x << ": " << x << endl
#define pb push_back
#define all(x) (x).begin(), (x).end()
#define fi first
#define se second
#define mod(x) ((x) % MOD)
#define gcd(a, b) __gcd(a, b)
#define lowbit(x) (x & -x)
typedef pair<int, int> PII;
typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
const int MOD = 1e9 + 7;
const double eps = 1e-9;
const ll INF = 0x3f3f3f3f3f3f3f3fll;
const int inf = 0x3f3f3f3f;
inline int read()
{
    int ret = 0, sgn = 1;
    char ch = getchar();
    while (ch < '0' || ch > '9')
    {
        if (ch == '-')
            sgn = -1;
        ch = getchar();
    }
    while (ch >= '0' && ch <= '9')
    {
        ret = ret * 10 + ch - '0';
        ch = getchar();
    }
    return ret * sgn;
}
inline void Out(int a)
{
    if (a > 9)
        Out(a / 10);
    putchar(a % 10 + '0');
}

ll gcd(ll a, ll b)
{
    return b == 0 ? a : gcd(b, a % b);
}

ll lcm(ll a, ll b)
{
    return a * b / gcd(a, b);
}
///快速幂m^k%mod
ll qpow(int m, int k, int mod)
{
    ll res = 1, t = m;
    while (k)
    {
        if (k & 1)
            res = res * t % mod;
        t = t * t % mod;
        k >>= 1;
    }
    return res;
}

// 快速幂求逆元
int Fermat(int a, int p) //费马求a关于b的逆元
{
    return qpow(a, p - 2, p);
}

///扩展欧几里得
int exgcd(int a, int b, int &x, int &y)
{
    if (b == 0)
    {
        x = 1;
        y = 0;
        return a;
    }
    int g = exgcd(b, a % b, x, y);
    int t = x;
    x = y;
    y = t - a / b * y;
    return g;
}

///使用ecgcd求a的逆元x
int mod_reverse(int a, int p)
{
    int d, x, y;
    d = exgcd(a, p, x, y);
    if (d == 1)
        return (x % p + p) % p;
    else
        return -1;
}

///中国剩余定理模板
ll china(int a[], int b[], int n) //a[]为除数,b[]为余数
{
    int M = 1, y, x = 0;
    for (int i = 0; i < n; ++i) //算出它们累乘的结果
        M *= a[i];
    for (int i = 0; i < n; ++i)
    {
        int w = M / a[i];
        int tx = 0;
        int t = exgcd(w, a[i], tx, y); //计算逆元
        x = (x + w * (b[i] / t) * x) % M;
    }
    return (x + M) % M;
}

int n, t;
int res;
int main()
{
    sd(t);
    while (t--)
    {
        sd(n);
        string s;
        cin >> s;
        int pos = 1;
        while (s.size() < n)
        {
            int len = s.size();
            for (int i = 1; i < s[pos - 1] - '0'; i++)
                s += s.substr(pos, len - pos);
            pos++;
        }
        ll ans = s.size() % MOD;
        while (pos <= n)
        {
            res = s[pos - 1] - '0';
            ans = (ans + ((ans - pos) * (res - 1)) % MOD + MOD) % MOD;
            pos++;
        }
        cout << ans % MOD << endl;
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值