区间赋值的数据结构都可以骗分,在数据随机的情况下,复杂度可以保证。
时间复杂度:O(nloglogn)
struct ODT{
struct node{
int l, r;
mutable LL v;
node(int l, int r = -1, LL v = 0) : l(l), r(r), v(v) {}
bool operator < (const node &o) const {return l < o.l;}
};
set<node> s;
ODT() {s.clear();}
auto split(int pos){
auto it = s.lower_bound(node(pos));
if (it != s.end() && it -> l == pos) return it;
it -- ;
int l = it -> l, r = it -> r;
LL v = it -> v;
s.erase(it);
s.insert(node(l, pos - 1, v));
return s.insert(node(pos, r, v)).first;
}
void assign(int l, int r, LL x){
auto itr = split(r + 1), itl = split(l);
s.erase(itl, itr);
s.insert(node(l, r, x));
}
void add(int l, int r, LL x){
auto itr = split(r + 1), itl = split(l);
for (auto it = itl; it != itr; it ++ ){
it -> v += x;
}
}
LL kth(int l, int r, int k){
vector<pair<LL, int>> a;
auto itr = split(r + 1), itl = split(l);
for (auto it = itl; it != itr; it ++ ){
a.push_back(pair<LL, int>(it -> v, it -> r - it -> l + 1));
}
sort(a.begin(), a.end());
for (auto [val, len] : a){
k -= len;
if (k <= 0) return val;
}
}
LL quickpow(LL a, int b, int mod){
a %= mod;
LL ans = 1;
while (b){
if (b & 1){
ans = ans * a % mod;
}
b >>= 1;
a = a * a % mod;
}
return ans;
}
LL powersum(int l, int r, int x, int mod){
auto itr = split(r + 1), itl = split(l);
LL ans = 0;
for (auto it = itl; it != itr; it ++ ){
ans = (ans + quickpow(it -> v, x, mod) * (it -> r - it -> l + 1) % mod) % mod;
}
return ans;
}
};