Codeforces Round #607 (Div. 1)——A. Cut and Paste

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;
 } 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值