文章目录
可以解决的问题
区间推平问题。将 [ l , r ] [l, r] [l,r]区间的值改为 x x x,随机数据下每次操作可认为是 O ( l o g N ) O(logN) O(logN),在只有区间推平操作的时候复杂度是正确的,其它的操作在区间推平的时候暴力做就可以了。
一个简单的例子(map实现)
个人认为map的实现会比set容易
将区间[l, r]的值改为v
我们首先使用一个map
map<int, int> mp;
mp[l]就表示[l, next[mp[l]])这一段区间的值是mp[l]
那么我们要做的就是将区间[l, r]切开,然后把map中所有下标小于等于r的全部删除,然后再令mp[l] = v即可
auto split = [&](int pos){ // 根据pos切开区间
if(mp.find(pos) == mp.end())
mp[pos] = prev(mp.lower_bound(pos)) -> second;
};
//接下来的操作就是将区间[l, r]删除并且令mp[l] = v
split(l), split(r + 1);
auto it = mp.find(l);
while(it -> first < r + 1){
// 有时需要处理删除区间所造成的影响...
it = mp.erase(it);
}
mp[l] = v;
模板题 896C — Willem, Chtholly and Seniorious
int seed;
int rng(){
int ret = seed;
seed = (seed * 7 + 13) % 1000000007;
return ret;
}
int qmi(int a, int b, int p){
int res = 1;
while(b){
if(b & 1) (res *= a) %= p;
(a *= a) %= p;
b >>= 1;
}
return res;
}
void solve() {
map<int, int> mp;
int n = read(), m = read();
mp[0] = mp[n + 1] = -1;
seed = read();
int vm = read();
vector<int> a(n + 1);
rep(i, 1, n)
a[i] = (rng() % vm) + 1;
rep(i, 1, n)
mp[i] = a[i];
auto split = [&](int pos){
if(mp.find(pos) == mp.end()){
mp[pos] = prev(mp.upper_bound(pos)) -> second;
}
};
while(m--){
int op = (rng() % 4) + 1;
int l = (rng() % n) + 1, r = (rng() % n) + 1;
if(l > r) swap(l, r);
int x;
if(op == 3) x = rng() % (r - l + 1) + 1;
else x = rng() % vm + 1;
if(op == 1){
split(l), split(r + 1);
auto it = mp.find(l);
while(it -> first < r + 1){
it -> second += x;
++it;
}
}
else if(op == 2){
split(l), split(r + 1);
auto it = mp.find(l);
while(it -> first < r + 1){
it = mp.erase(it);
}
mp[l] = x;
}
else if(op == 3){
vector<array<int, 2>> vs;
split(l), split(r + 1);
auto it = mp.find(l);
while(it -> first < r + 1){
auto ne = next(it);
vs.push_back({it -> second, ne -> first - it -> first});
++it;
}
sort(vs.begin(), vs.end());
for(auto p : vs){
if(x <= p[1]){wt(p[0]); break;}
x -= p[1];
}
}
else{
int y = rng() % vm + 1;
vector<array<int, 2>> vs;
split(l), split(r + 1);
auto it = mp.find(l);
while(it -> first < r + 1){
auto ne = next(it);
vs.push_back({it -> second, ne -> first - it -> first});
++it;
}
int ans = 0;
for(auto p : vs)
(ans += p[1] * qmi(p[0] % y, x, y) % y) %= y;
// for(auto p : vs) cout << p[0] << ' ' << p[1] << '\n';
wt(ans);
}
}
}