H - Figurines

题意:

有一个展览架,N个不同编号的模型,每天会往上放上模型或拿走模型。同时有一个算法,xi+1=(xi+yi)modNx_{i+1}=(x_{i}+y_i) mod N,其中yiy_idid_i天时,展览架中编号大于等于xix_i的个数。给出每天放上和拿走模型的情况,和每个did_i,求xNx_N

解析:

由于N为1e5级别,无法直接开线段树或者set存每一天的状态,所以需要用可持久化线段树优化一下,基本属于模板题。

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
#include <bits/stdc++.h>

using namespace std;
#define fast \
ios_base::sync_with_stdio(false); \
cin.tie(NULL);
const int N = 5e6 + 10;
const int M = 1e6 + 10;
const int INF = 0x3f3f3f3f;
const long long LINF = 0x3f3f3f3f3f3f3f3f;
const int mod = 1e9 + 7;
const double eps = 1e-3;
#define lson (root << 1)
#define rson (root << 1 | 1)

int T[N], ls[N], rs[N], sum[N], idx;

void build(int &root, int l, int r) {
root = ++idx;
sum[root] = 0;
if(l == r) return;
int mid = (l + r) >> 1;
build(ls[root], l, mid);
build(rs[root], mid + 1, r);
}
void update(int &root, int l, int r, int pre, int pos, int val) {
root = ++idx;
ls[root] = ls[pre], rs[root] = rs[pre];
sum[root] = sum[pre] + val;
if(l == r) return;
int mid = (l + r) >> 1;
if(pos <= mid) update(ls[root], l, mid, ls[pre], pos, val);
else update(rs[root], mid + 1, r, rs[pre], pos, val);
}
int query(int root, int l, int r, int k) {
if(k <= l) return sum[root];
if(l == r) return sum[root];
int mid = (l + r) >> 1;
int res = 0;
if(k <= mid) res += query(ls[root], l, mid, k);
res += query(rs[root], mid + 1, r, k);
return res;
}
int n;
pair<int,int> solve(string s) {
int c = s[0] == '+'?1:-1;
int res = 0, len = s.size();
for (int i = 1; i < len; i++) {
res = res * 10 + s[i] - '0';
}
return {res, c};
}
int D[N];
int main(){
ios::sync_with_stdio(false);
string s;
cin >> n;
getline(cin, s);
build(T[0], 0, n - 1);
int cnt = 0;
for (int i = 1; i <= n; i++) {
getline(cin, s);
stringstream ss;
ss << s;
while(ss >> s) {
auto res = solve(s);
cnt++;
update(T[cnt], 0, n - 1, T[cnt - 1], res.first, res.second);
}
D[i] = cnt;
}
int x = 0;
for (int i = 1; i <= n; i++) {
int d;
cin >> d;
int res = query(T[D[d]], 0, n - 1, x);
x = (x + res) % n;
}
cout << x << '\n';
return 0;
}