H - Figurines
题意:
有一个展览架,N个不同编号的模型,每天会往上放上模型或拿走模型。同时有一个算法, x i + 1 = ( x i + y i ) m o d N x_{i+1}=(x_{i}+y_i) mod N xi+1=(xi+yi)modN,其中 y i y_i yi为 d i d_i di天时,展览架中编号大于等于 x i x_i xi的个数。给出每天放上和拿走模型的情况,和每个 d i d_i di,求 x N x_N xN
解析:
由于N为1e5级别,无法直接开线段树或者set存每一天的状态,所以需要用可持久化线段树优化一下,基本属于模板题。
代码
#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;
}