src 给1e6长的字符串,构造一个连续排列的金字塔,类似蛇形地放入。求第ai行字符ci有几个。ai有1e18,但询问k只有1e5。
对单个询问,容易想到求前后缀。因为第ai行之前的长度,能用求和公式算出来,虽然溢出longlong,但我们只需要取模能知道ai开始和结尾的信息即可。
这道题内存只给 65536K(65MB),特意去卡 1e6*26的二维数组。(int数组这样开接近100MB),只好用一维数组。我把询问离线存下,按字母排序,每次字母改变时,重新计算前后缀。
注意,求和公式的时候,涉及1e18数量级的乘法。最好每个数都保证在模范围内。
#pragma comment(linker, "/STACK:102400000,102400000")
#define _debug(x) cerr<<#x<<" = "<<(x)<<endl;fflush(stdout)
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int MAXN = 1e6 + 77;
const ll INF = 0x3f3f3f3f;
const ll MOD = 1e9 + 7;
struct Query {
ll ai;
char ci;
int i;
bool operator<(const Query &q) const {
return ci < q.ci;
}
} ask[50004];
ll n, k;
ll ans[50004];
int ser[MAXN];
int pre[MAXN];
char s[MAXN];
char ch[2];
char ci;
char lci = -1;
ll ai;
ll rlen, plen, timz, tlen, slen;
inline void recalc(char c) {
for (ll i = 1, j = slen; i <= slen; ++i, --j) {
pre[i] = pre[i - 1];
ser[i] = ser[i - 1];
if (s[i] == c)pre[i]++;
if (s[j] == c)ser[i]++;
}
}
int main() {
// ios::sync_with_stdio(false);
// cin.tie(nullptr);
scanf("%lld %s", &n, s + 1);
scanf("%lld", &k);
slen = strlen(s + 1);
for (int i = 0; i < k; ++i) {
scanf("%lld %s", &ai, ch);
ci = ch[0] - 'A';
ask[i] = {ai, ci, i};
}
sort(ask, ask + k);
for (int id, i = 0; i < k; i++) {
ai = ask[i].ai;
ci = ask[i].ci;
id = ask[i].i;
if (lci != ci)
recalc(ci + 'A');
lci = ci;
if (ai % 2 == 0) {
rlen = (((ai - 1) % slen) * ((ai / 2ll) % slen)) % slen;
} else {
rlen = ((((ai - 1) / 2ll) % slen) * (ai % slen)) % slen;
}
// rest before the ai line
plen = (slen - rlen);
if (ai <= plen) {
ans[id] = ser[plen] - ser[plen - ai];
continue;
}
timz = (ai - plen) / slen;
tlen = (ai - plen) % slen;
ans[id] = ser[plen] * 1ll + timz * pre[slen] + pre[tlen] * 1ll;
}
for (int i = 0; i < k; i++) {
printf("%lld\n", ans[i]);
}
return 0;
}
/*
8000000000000
JANJETINA
5
6000000000001 J
6000000000002 A
6000000000003 N
6000000000004 N
6000000000005 N
8000000000000
AB
10
60000000000000001 A
60000000000000001 B
60000000000000002 A
60000000000000002 B
60000000000000003 A
60000000000000003 B
60000000000000004 A
60000000000000004 B
60000000000000005 A
60000000000000005 B
8000000000000
AB
10
1 A
1 B
2 A
2 B
3 A
3 B
4 A
4 B
5 A
5 B
8000000000000
AB
5
60000000000000000 A
60000000000000001 A
60000000000000002 A
60000000000000003 A
60000000000000004 A
* */