C. Mark and His Unfinished Essay

time limit per test2 seconds

memory limit per test256 megabytes

input standard input

output standard output

One night, Mark realized that there is an essay due tomorrow. He hasn't written anything yet, so Mark decided to randomly copy-paste substrings from the prompt to make the essay.

More formally, the prompt is a string ss of initial length nn. Mark will perform the copy-pasting operation c times. Each operation is described by two integers l and r, which means that Mark will append letters slsl+1…sr to the end of string s. Note that the length of s increases after this operation.

Of course, Mark needs to be able to see what has been written. After copying, Mark will ask qq queries: given an integer kk, determine the kk-th letter of the final string ss.

Input

The first line contains a single integer tt (1≤t≤1000) — the number of test cases.

The first line of each test case contains three integers nn, cc, and q (1≤n≤2⋅10^5, 1≤c≤40, and 1≤q≤10^4) — the length of the initial string s, the number of copy-pasting operations, and the number of queries, respectively.

The second line of each test case contains a single string ss of length n. It is guaranteed that s only contains lowercase English letters.

The following c lines describe the copy-pasting operation. Each line contains two integers l and r (1≤l≤r≤10^18). It is also guaranteed that r does not exceed the current length of ss.

The last qq lines of each test case describe the queries. Each line contains a single integer kk (1≤k≤10^18). It is also guaranteed that k does not exceed the final length of s.

It is guaranteed that the sum of nn and qq across all test cases does not exceed 2⋅10^5 and 10^4, respectively.

Output

For each query, print the k-th letter of the final string s.

Example

input

Copy

2
4 3 3
mark
1 4
5 7
3 8
1
10
12
7 3 3
creamii
2 3
3 4
2 9
9
11
12

output

Copy

m
a
r
e
a
r

Note

In the first test case, the copy-paste process is as follows.

  • The first step is pasting string markmark at the end, yielding the string markmark.
  • The second step is pasting string marmar at the end, yielding the string markmarkmar.
  • The third step is pasting string rkmarkrkmark at the end, yielding the string markmarkmarrkmark.

In the second test case, the copy-paste process is as follows.

  • The first step is pasting string rere at the end, yielding the string creamiire.
  • The second step is pasting string eaea at the end, yielding the string creamiireea.
  • The third step is pasting string reamiirereamiire at the end, yielding the string creamiireeareamiire

首先这题时间不可能让我们按字符链接,所以我们需要另想办法比如说逆推,既然正向链接字符串无法解决,不妨逆推。

逆推的过程,我们需要先确定k所在的长度区间,然后不停向前面区间推进。

我们知道length1[i+1]=length1[i] +(r[i]-l[i])+1;

如果k在这个区间及是(length1[i],length1[i+1])

那么k=k-(lenght1[i+1]-r[i]-1)就是向前面区间推进了。

推进最初始的s字符串,让它输出。

代码如下:

#include <iostream>
#include <string>
using namespace std;
int main()
{
    int t;
    cin >> t;
    while (t > 0)
    {
        int n, c, q;
        cin >> n >> c >> q;
        string s;
        cin >> s;
        long long length1[100], l[100], r[100], k[10000];           /*length1是字符串长度*/
        length1[0] = s.size();                                      /*首地址先赋进去*/
        for (int i = 0; i < c; i++)
        {
            cin >> l[i] >> r[i];
            l[i]--;                                                 /*以为我用的是从0开始所以需要减一*/
            r[i]--;
            length1[i + 1] = (r[i] - l[i]) + length1[i]+1;          /*长度增加*/
        }
        for (int i = 0; i < q; i++)
        {
            cin >> k[i];
        }
        for(int i=0;i<q;i++)
        {
            k[i]--;                                                 /*首位从0开始所以减一*/
        }
        for (long long i = 0; i < q; i++)
        {
            while (k[i] >= n)
            {
                long long index = 0;
                for (long long j = 0; j <= c; j++)
                {
                    if (k[i] < length1[j])
                    {
                        index = j;                                 /*找到每次k[i]所在的长度区间*/
                        break;
                    }
                }
                k[i]=k[i]-(length1[index]-r[index-1]-1);          /*k[i]向前推*/
            }
            cout<<s[k[i]]<<endl;
        }
        t--;
    }
    return 0;
}

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值