# 洛谷P3245 [HNOI2016]大数(莫队)

## Sol

```#include <bits/stdc++.h>
#define LL long long
using namespace std;
const int MAXN = 1e6 + 10;
int mod;
template <typename A, typename B>
inline void mul2(A &x, B y) {
x = 1ll * x * y % mod;
}
template <typename A, typename B>
inline int mul(A x, B y) {
return 1ll * x * y % mod;
}
template <typename A, typename B>
inline int add(A x, B y) {
return x + y >= mod ? x + y - mod : x + y;
}
char c = getchar();
int x = 0, f = 1;
while (c < '0' || c > '9') {
if (c == '-')
f = -1;
c = getchar();
}
while (c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
return x * f;
}
int N, Q, belong[MAXN], block, l, r;
LL now, ans[MAXN];
char s[MAXN];

namespace Sub3 {
int pro[MAXN], num, date[MAXN], cnt[MAXN];
void Des() {
for (int i = 1; i <= N + 1; i++) date[++num] = pro[i];
sort(date + 1, date + num + 1);
num = unique(date + 1, date + num + 1) - date - 1;
for (int i = 1; i <= N + 1; i++) pro[i] = lower_bound(date + 1, date + num + 1, pro[i]) - date;
}
struct Query {
int l, r, id;
bool operator<(const Query &rhs) const {
return belong[l] == belong[rhs.l] ? r < rhs.r : belong[l] < belong[rhs.l];
}
} q[MAXN];
now += cnt[x];
cnt[x]++;
}
void Delet(int x) {
cnt[x]--;
now -= cnt[x];
}
void solve() {
block = sqrt(N);
for (int i = 1; i <= N; i++) belong[i] = (i - 1) / block + 1;
for (int i = N, base = 1; i >= 1; i--, mul2(base, 10)) pro[i] = add(pro[i + 1], mul((s[i] - '0'), base));
Des();
for (int i = 1; i <= Q; i++) q[i].l = read(), q[i].r = read() + 1, q[i].id = i;
sort(q + 1, q + Q + 1);
l = 1, r = 0;
for (int i = 1; i <= Q; i++) {
while (r > q[i].r) Delet(pro[r--]);
while (l < q[i].l) Delet(pro[l++]);
ans[q[i].id] = now;
}
for (int i = 1; i <= Q; i++) cout << ans[i] << '\n';
}
}  // namespace Sub3

namespace Sub1 {
int cnt[MAXN], a[MAXN];
struct Query {
int l, r, id;
bool operator<(const Query &rhs) const {
return belong[l] == belong[rhs.l] ? r < rhs.r : belong[l] < belong[rhs.l];
}
} q[MAXN];
void Add(int x, int opt) {
if (opt) {
if (x == 0)
now += r - l + 1;
} else {
now += cnt[0];
}
cnt[x]++;
}
void Delet(int x, int opt) {
cnt[x]--;
if (opt) {
if (x == 0)
now -= r - l + 1;
} else {
now -= cnt[0];
}
}
void solve() {
block = sqrt(N);
for (int i = 1; i <= N; i++) belong[i] = (i - 1) / block + 1, a[i] = (s[i] - '0') % 2;
for (int i = 1; i <= Q; i++) q[i].l = read(), q[i].r = read(), q[i].id = i;
sort(q + 1, q + Q + 1);
l = 1, r = 0;
for (int i = 1; i <= Q; i++) {
while (r < q[i].r) Add(a[++r], 1);
while (r > q[i].r) Delet(a[r--], 1);
while (l < q[i].l) Delet(a[l++], 0);
while (l > q[i].l) Add(a[--l], 0);
ans[q[i].id] = now;
}
for (int i = 1; i <= Q; i++) cout << ans[i] << '\n';
}
}

namespace Sub2 {
int cnt[MAXN], a[MAXN], len[MAXN];
struct Query {
int l, r, id;
bool operator < (const Query &rhs) const {
return belong[l] == belong[rhs.l] ? r < rhs.r : belong[l] < belong[rhs.l];
}
}q[MAXN];
void Add(int x, int opt, int pos) {
cnt[x]++;
if(opt) {
if(x == 0 || x == 5) now += r - l + 1;
} else {
now += cnt[0] + cnt[5];
}

}
void Delet(int x, int opt, int pos) {
if(opt) {
if(x == 0 || x == 5) now -= r - l + 1;
} else {
now -= cnt[0] + cnt[5];
}
cnt[x]--;
}
void solve() {
block = sqrt(N);
for(int i = 1; i <= N; i++) belong[i] = (i - 1) / block + 1, a[i] = s[i] - '0';
for(int i = 1; i <= Q; i++) q[i].l = read(), q[i].r = read(), q[i].id = i;
sort(q + 1, q + Q + 1);
l = 1, r = 0;
for(int i = 1; i <= Q; i++) {
while(l > q[i].l)
while(r > q[i].r)
Delet(a[r], 1, r), r--;
while(l < q[i].l)
Delet(a[l], 0, l), l++;
while(r < q[i].r)
ans[q[i].id] = now;
}
for(int i = 1; i <= Q; i++) cout << ans[i] << '\n';
}

}

int main() {
scanf("%s", s + 1);
N = strlen(s + 1);
if (mod == 2)
Sub1::solve();
else if (mod == 5)
Sub2::solve();
else
Sub3::solve();
return 0;
}
/*
11
1211
1
1 4
*/```

0 条评论

• ### loj#6031. 「雅礼集训 2017 Day1」字符串(SAM 广义SAM 数据分治)

考虑K比较小的情况，可以直接暴力建SAM， 枚举w的子串算出现次数。询问用个 的vector记录一下每次在vector里二分就好。

• ### BZOJ2535: [Noi2010]Plane 航空管制2(拓扑排序 贪心)

首先不难想到拓扑排序，但是直接对原图按\(k\)从小到大拓扑排序是错的。因为当前的\(k\)大并不意味着后面的点\(k\)也大

• ### 作业比赛编号 : 100000575 - 《算法笔记》3.1小节——入门模拟->简单模拟

网址：http://codeup.cn/contest.php?cid=100000575

• ### 2189 数字三角形W

2189 数字三角形W 时间限制: 1 s 空间限制: 32000 KB 题目等级 : 黄金 Gold 题目描述 Description 数字三角...

• ### BZOJ2535: [Noi2010]Plane 航空管制2(拓扑排序 贪心)

首先不难想到拓扑排序，但是直接对原图按\(k\)从小到大拓扑排序是错的。因为当前的\(k\)大并不意味着后面的点\(k\)也大

• ### loj#6031. 「雅礼集训 2017 Day1」字符串(SAM 广义SAM 数据分治)

考虑K比较小的情况，可以直接暴力建SAM， 枚举w的子串算出现次数。询问用个 的vector记录一下每次在vector里二分就好。