codeforces 589 C. Polycarp's Masterpiece

来源:互联网 发布:软件设计师视频下载 编辑:程序博客网 时间:2024/06/05 05:36
C. Polycarp's Masterpiece
time limit per test
1 second
memory limit per test
512 megabytes
input
standard input
output
standard output

Inspired by success of Joanne Rowling and her fantasy series of Harry Potter, Polycarp decided to create his own masterpiece. He has already picked a name for his future bestseller — string s.

Polycarp faced a number of difficulties while he was working on the main story of his book so he decided to become Malevich in a literature and create his own "Black Square".

Chapters of his masterpiece were written by Polycarp in n days. He started from writing down the string s. Every day (during the following n days) he did the following procedure: on the i-th day he added to the right of current text t its ki-th circular shift. It means that every day content of his masterpiece doubled in size.

Circular shift of a string r is defined as a string resulted after movement of the last character of r to the first position in the string. As an example: circular shift of «masterpiece» is «emasterpiec». The i-th circular shift of a string r is defined as a string resulted after applying i subsequent circular shifts of the string r (e.g., the third circular shift of «masterpiece» is «ecemasterpi»).

After n days of tedious work Polycarp managed to write a very long text deserving the efforts made. However, text of his masterpiece was so long that it was nearly impossible to do any analysis of its content.

Help Polycarp to answer m requests about his masterpiece: for the j-th request you will need to find how many times a letter cj is contained in a substring of his masterpiece starting from position lj and ending at rj inclusively.

Input

The first line contains a name of the masterpiece — string s. The string s contains only lowercase latin letters and its length is between 1 and 100 inclusively.

The second line contains a pair of integer numbers n and m (1 ≤ n ≤ 105,  1 ≤ m ≤ 105) — a number of days Polycarp worked on his masterpiece and a number of requests you need to answer for the text respectively.

The next line consists of n integer numbers ki (0 ≤ ki ≤ 100) — circular shifts used during n days of work.

Following m lines contains two integer numbers lj, rj and a lowercase latin letter cj each — requests description. For each request you need to count number of times letter cj is contained in a substring of the masterpiece from position lj to rj inclusively. Positions are numerated starting from 1. It is guaranteed that 1 ≤ lj ≤ rj ≤ 1018 and both lj and rj do not exceed length of the masterpiece.

Output

Output should contain m lines, where the j-th line contains the answer on the j-th request.

Sample test(s)
input
masterpiece1 331 22 m9 14 e8 15 p
output
240
input
polycarp1 202 15 p1 16 p
output
24

考虑k只有100,所以从k下手,我们定义f(x, c)表示字母c在[1, c]区间出现的次数,对于一个询问[l, r], c,ans = f(r, c) - f(l - 1, c),所以问题就落在怎么求f(x, c),对于(2 ^ y) <= x, 前(2 ^ y)个都是可以直接计算,后面的是通过前面的经过一个旋转操作得到,去掉前k个就和前面的顺序一样了,所以f(x, c) = c在区间[1, 2 ^ y]的个数 + c在前k个字符的个数 + f(x - 2 ^ y - k, c), 所以一次询问的复杂度为O(log(x))

#include <iostream>#include <cstdio>#include <string>#include <cstring>#include <vector>using namespace std;#define LL long longconst int N = 1e5 + 5;char str[N];int str_len;char bac[N];int bac_len;vector<char> bac_str[70];int limit = 0;int k[N];int sum[N][30];void predo(char str[]) {    str_len = strlen(str);bac_len = str_len;    for(int i = 0; i < str_len; ++i) {        if(i == 0) {            sum[0][str[i] - 'a'] = 1;        } else {            for(int j = 0; j < 30; ++j) {                sum[i][j] = sum[i - 1][j];            }            ++sum[i][str[i] - 'a'];        }bac[i] = str[i];    }}void shift(int id, int x) {for(int i = bac_len - x; i < bac_len; ++i) {bac_str[id].push_back(bac[i]);}if(bac_len < (limit - id) * 100) {int new_len = bac_len;for(int i = bac_len - x; i < bac_len - x + bac_len; ++i) {bac[new_len++] = bac[i % bac_len];}bac_len = new_len;} else {bac_len -= x;}}LL ss[70][30][105];LL gao(LL x, char ch) {if(x == 0) return 0;if(x <= str_len) {return sum[x - 1][ch - 'a'];}LL pre = sum[str_len - 1][ch - 'a'];LL pre_len = str_len;int p = 0;while(pre_len * 2 <= x) {pre *= 2;pre_len *= 2;++p;}//cout<<pre_len<<' '<<pre<<' '<<p<<endl;if(x - pre_len > k[p]) {LL add = ss[p][ch - 'a'][bac_str[p].size()];//for(int i = 0; i < bac_str[p].size(); ++i) {//if(bac_str[p][i] == ch) ++add;//}return pre + add + gao(x - pre_len - k[p], ch);} else {LL add = ss[p][ch - 'a'][x - pre_len];//for(int i = 0; i < x - pre_len; ++i) {//if(bac_str[p][i] == ch) ++add;//}return pre + add;}}int main() {    scanf("%s", str);    predo(str);    int n, m;    scanf("%d%d", &n, &m);LL tmp_len = str_len;while(tmp_len < 2 * 1e18) {++limit;tmp_len *= 2;}tmp_len = str_len;    for(int i = 0; i < n; ++i) {        scanf("%d", &k[i]);if(i <= limit) {k[i] %= tmp_len;shift(i, k[i]);tmp_len *= 2;}    }for(int i = 0; i < 70; ++i) {for(int j = 0; j < bac_str[i].size(); ++j) {for(int l = 0; l < 30; ++l) {ss[i][l][j + 1] = ss[i][l][j];}char ch = bac_str[i][j] - 'a';++ss[i][ch][j + 1];}}//for(int i = 0; i < 1; ++i) {//for(int j = 0; j < bac_str[i].size(); ++j) {//cout<<bac_str[i][j];//}//cout<<endl;//}    char ch[3];    for(int i = 0; i < m; ++i) {        LL l, r; scanf("%I64d%I64d", &l, &r);        scanf("%s", ch);        printf("%I64d\n", gao(r, ch[0]) - gao(l - 1, ch[0]));    }    return 0;}

0 0