珂朵莉树模板(ODT)
解决区间赋值 + 区间\(k\)次方和(数据随机)
#include<bits/stdc++.h>
#define IT set<Node>::iterator
using namespace std;
typedef long long ll;
const ll mod = 1e9+7;
struct Node{
int l, r;
mutable ll v;
bool operator < (const Node &p) const{
return l < p.l;
}
};
set<Node> s;
IT split(int pos){
IT it = s.lower_bound(Node{pos,pos,0});
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;
}
//split要先r+1, 再l
void update(int l, int r, ll v){
IT rit = split(r+1), lit = split(l);
s.erase(lit, rit);
s.insert(Node{l, r, v});
}
ll fpow(ll a, ll b){
ll ans = 1;
while(b){
if(b &1)
ans = ans * a % mod;
a = a * a % mod;
b /= 2;
}
return ans;
}
ll query(int l, int r, ll k){
IT rit = split(r+1), lit = split(l);
ll ans = 0;
for(; lit != rit;lit++)
ans += fpow(lit->v, k) * 1ll * (lit->r - lit->l);
return ans;
}
int main(){
int n, m;
scanf("%d%d", &n, &m);
s.insert(Node{1, n, 0ll});
int id, l, r;
ll x;
while(m--){
scanf("%d%d%d%lld", &id, &l, &r, &x);
if(id == 1)
update(l, r, x);
else
printf("%lld\n", query(l, r, x));
}
}