voidrange_add(int l , int r , int val){ range R = spilt(r + 1); range L = spilt(l); for(range i = L; i != R; i ++){ i -> val += val; } }
区间快速幂之和
即求:
对每一段区间暴力快速幂即可。
ll Pow(ll a , ll n , ll HA){ if(n == 0){ return1; } if(n == 1){ return a % HA; } ll c = Pow(a , n / 2 , HA); if(n % 2 == 0){ return c * c % HA; } else{ return (c * c * a) % HA; } }
ll range_pow(int l , int r , ll val , ll HA){ range R = spilt(r + 1); range L = spilt(l); ll ans = 0; for(range i = L; i != R; i ++){ ans += (ll)(i -> r - i -> l + 1) * Pow(i -> v , val , HA); ans %= HA; } return ans; }
区间第k大
原理也很简单,就是把那段区间的元素丢入一个vector,然后排序。
ll range_query(int l , int r , int k){ #define pairs pair<ll , int>
vector<pairs > V; V.clear(); range R = spilt(r + 1); range L = spilt(l); for(range i = L; i != R; i ++){ V.push_back(pairs(i -> val , i -> r - i -> l + 1)); } sort(V.begin() , V.end()); ll sum = 0; for(vector<pairs > :: iterator i = V.begin(); i != V.end(); i ++){ sum += i -> second; if(sum >= k){ return i -> first; } } return-1; }
操作模板
不知道大家看出来了没有,珂朵莉树的操作大部分是有模板可以套的。
模板如下
voidchange(int l , int r , int val){ range R = spilt(r + 1); range L = spilt(l); for(range i = L; i != R; i ++){ ……………… } }
#define ll long long #define I inline #define N 100001
usingnamespacestd;
int n , m , s; int a[N];
namespace ODT{ #define range set<Node> :: iterator
structNode{ int l , r; mutable ll val; booloperator < (const Node &b) const{ return l < b.l; } };
set<Node > S;
voidbuild(int n){ for(int i = 1; i <= n; i ++){ S.insert(Node{i , i , a[i]}); } }
range spilt(int pos){ range it = S.lower_bound((Node){pos , pos , -1}); if(it != S.end() && it -> l == pos){ return it; } it --; Node ins = *it; S.erase(it); S.insert((Node){ins.l , pos - 1 , ins.val}); return S.insert((Node){pos , ins.r , ins.val}).first; }
voidassign(int l , int r , ll val){ range R = spilt(r + 1); range L = spilt(l); S.erase(L , R); S.insert(Node{l , r , val}); }
voidrange_add(int l , int r , int val){ range R = spilt(r + 1); range L = spilt(l); for(range i = L; i != R; i ++){ i -> val += val; } }
ll Pow(ll a , ll n , ll HA){ if(n == 0){ return1; } if(n == 1){ return a % HA; } ll c = Pow(a , n / 2 , HA) % HA; if(n % 2 == 0){ return (c * c) % HA; } else{ return (((c * c) % HA) * a) % HA; } }
ll range_pow(int l , int r , ll val , ll HA){ range R = spilt(r + 1); range L = spilt(l); ll ans = 0; for(range i = L; i != R; i ++){ ans += (ll)(i -> r - i -> l + 1) * Pow(i -> val , val , HA); ans %= HA; } return ans; }
ll range_query(int l , int r , int k){ #define pairs pair<ll , int>
vector<pairs > V; V.clear(); range R = spilt(r + 1); range L = spilt(l); for(range i = L; i != R; i ++){ V.push_back(pairs(i -> val , i -> r - i -> l + 1)); } sort(V.begin() , V.end()); ll sum = 0; for(vector<pairs > :: iterator i = V.begin(); i != V.end(); i ++){ sum += i -> second; if(sum >= k){ return i -> first; } } return-1; } }
ll seed, vmax;
I ll rnd(){ ll ret = seed; seed = (seed * 7 + 13) % 1000000007; return ret; }