Codeforces Round #607 (Div. 1)——A. Cut and Paste
We start with a string s consisting only of the digits 1, 2, or 3. The length of s is denoted by |s|. For each i from 1 to |s|, the i-th character of s is denoted by si.
There is one cursor. The cursor’s location ℓ is denoted by an integer in {0,…,|s|}, with the following meaning:
If ℓ=0, then the cursor is located before the first character of s.
If ℓ=|s|, then the cursor is located right after the last character of s.
If 0<ℓ<|s|, then the cursor is located between sℓ and sℓ+1.
We denote by sleft the string to the left of the cursor and sright the string to the right of the cursor.
We also have a string 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←sright, then set s←sleft.
The Paste action. Append the value of c to the end of the string s. Note that this doesn’t modify 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, stop. Otherwise, return to step 1.
You’re given the initial string s and the integer x. What is the length of s when the procedure stops? Since this value may be very large, only find it modulo 109+7.
It is guaranteed that ℓ≤|s| at any time.
Input
The first line of input contains a single integer t (1≤t≤1000) 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≤106). The second line of each test case consists of the initial string s (1≤|s|≤500). It is guaranteed, that s consists of the characters “1”, “2”, “3”.
It is guaranteed that the sum of x in a single file is at most 106. It is guaranteed that in each test case before the procedure will stop it will be true that ℓ≤|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 109+7.
Example
inputCopy
4
5
231
7
2323
6
333
24
133321333
outputCopy
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.
Step 2, Cut once: we get s= 2 and c= 31.
Step 3, Paste sℓ= 2 times: we get s= 23131.
Step 4: ℓ=1≠x=5, so we return to step 1.
Step 1, Move once: we get ℓ=2.
Step 2, Cut once: we get s= 23 and c= 131.
Step 3, Paste sℓ= 3 times: we get s= 23131131131.
Step 4: ℓ=2≠x=5, so we return to step 1.
Step 1, Move once: we get ℓ=3.
Step 2, Cut once: we get s= 231 and c= 31131131.
Step 3, Paste sℓ= 1 time: we get s= 23131131131.
Step 4: ℓ=3≠x=5, so we return to step 1.
Step 1, Move once: we get ℓ=4.
Step 2, Cut once: we get s= 2313 and c= 1131131.
Step 3, Paste sℓ= 3 times: we get s= 2313113113111311311131131.
Step 4: ℓ=4≠x=5, so we return to step 1.
Step 1, Move once: we get ℓ=5.
Step 2, Cut once: we get s= 23131 and c= 13113111311311131131.
Step 3, Paste sℓ= 1 times: we get s= 2313113113111311311131131.
Step 4: ℓ=5=x, so we stop.
At the end of the procedure, s has length 25.
***题意:***他有四个操作,我们按他的操作操作x轮后,看字符串的长度有多长。
***思路:***因为数据较大,所有完全模拟是必然会超时的,我们只要先模拟到字符串长度超过x就行了,因为最多操作x次,后面的字符串我们只要知道长度就行了,里面是什么内容并不重要。操作完了之后直接虚拟模拟一下剩下的操作次数,算出最终的长度就行了。(注意mod计算在减的时候要先加mod)
***提醒:***在进行字符串操作时最好用string的函数,如果用strcpy等等极易超时。(我就因为这个wa了无数发)
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
string s;
char c[5000007];
char b[5000007];
const ll mod=1e9+7;
inline ll qsc(ll a,ll b)
{
ll ans=0;
while(b)
{
if(b&1) ans=(ans+a)%mod;
a=(a+a)%mod;
b>>=1;
}
return ans;
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
int n;
scanf("%d",&n);
cin>>s;
ll i=0;
ll len=s.length();
while(i+1<=n&&len<=n)
{
i++;
string a=s.substr(i);
for(int j=0;j<s[i-1]-'0'-1;j++)
{
s+=a;
//cout<<s<<endl;
}
len=s.length();
}
len=s.length();
for(int j=i+1;j<=n;j++)
{
if(s[j-1]-'0'==2)
{
len=(qsc(2,len)%mod-j+mod)%mod;
}else if(s[j-1]-'0'==3)
{
len=(qsc(3,len)%mod-qsc(2,j)+mod)%mod;
}else
{
while(s[j-1]-'0'==1)
{
j++;
}
j--;
}
}
printf("%lld\n",len);
}
return 0;
}