# 珂朵莉树 | “朝闻道”知识分享大赛

• 区间加

• 区间赋值

• 求区间第k大值

• 求区间n次方和

C. Willem, Chtholly and Seniorious

Physical Education Lessons

E. Colorful Operations

``````template<typename T>
struct ODT//珂朵莉树
{
struct Node
{
int l,r;
mutable T v;
Node(int _l,int _r = -1,T _v = 0):l(_l),r(_r),v(_v){}
bool operator<(const Node&o) const {return l < o.l;}
};
set<Node> S;
void insert(int l,int r,T v){//往set中插入结点
S.insert(Node(l,r,v));
}
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;
T v = it->v;
S.erase(it);
S.insert(Node(l,pos - 1,v));
return S.insert(Node(pos,r,v)).first;
}
void add(int l,int r,T v){  //区间加
for(auto end = split(r + 1),it = split(l);it != end;it++)
it->v += v;
}
void assign(int l,int r,T v){   //区间赋值
auto end = split(r + 1),begin = split(l);
S.erase(begin,end);
S.insert(Node(l,r,v));
}
T get_k(int l,int r,int k){ //区间第k大的数
vector<pair<T,int>> v;
for(auto end = split(r + 1),it = split(l);it != end;it++){
v.push_back({it->v,it->r - it->l + 1});
}
sort(v.begin(),v.end());
for(auto x : v){
k -= x.second;
if(k <= 0)  return x.first;
}
return -1;
}
T sum_pow(int l,int r,int k,int p){ //区间[l,r]的k次幂之和
ll res = 0;
for(auto end = split(r + 1),it = split(l);it != end;it++){
res = (res + 1ll * (it->r - it->l + 1) * fpow(it->v,k,p) % p) % p;
}
return res;
}
};
``````

``````#include<bits/stdc++.h>

using namespace std;

typedef long long ll;

const int N = 1e5 + 10,mod = 1e9 + 7;
int n,m,seed,vmax;
int a[N];

ll fpow(ll a,ll b,ll p)
{
a %= p;
ll res = 1;
while (b)
{
if(b & 1)   res = res * a % p;
a = a * a % p;
b >>= 1;
}
return res;
}

template<typename T>
struct ODT//珂朵莉树
{
struct Node
{
int l,r;
mutable T v;
Node(int _l,int _r = -1,T _v = 0):l(_l),r(_r),v(_v){}
bool operator<(const Node&o) const {return l < o.l;}
};
set<Node> S;
void insert(int l,int r,T v){//往set中插入结点
S.insert(Node(l,r,v));
}
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 add(int l,int r,T v){  //区间加
for(auto end = split(r + 1),it = split(l);it != end;it++)
it->v += v;
}
void assign(int l,int r,T v){   //区间赋值
auto end = split(r + 1),begin = split(l);
S.erase(begin,end);
S.insert(Node(l,r,v));
}
T get_k(int l,int r,int k){ //区间第k大的数
vector<pair<T,int>> v;
for(auto end = split(r + 1),it = split(l);it != end;it++){
v.push_back({it->v,it->r - it->l + 1});
}
sort(v.begin(),v.end());
for(auto x : v){
k -= x.second;
if(k <= 0)  return x.first;
}
return -1;
}
T sum_pow(int l,int r,int k,int p){ //区间[l,r]的k次幂之和
ll res = 0;
for(auto end = split(r + 1),it = split(l);it != end;it++){
res = (res + 1ll * (it->r - it->l + 1) * fpow(it->v,k,p) % p) % p;
}
return res;
}
};

int rnd()
{
int ret = seed;
seed = (seed * 7ll + 13) % mod;
return ret;
}

int main()
{
cin.tie(nullptr)->sync_with_stdio(false);

cin >> n >> m >> seed >> vmax;
ODT<ll> odt;
for(int i = 1;i <= n;i++)
{
a[i] = (rnd() % vmax) + 1;
odt.insert(i,i,a[i]);
}

int op,l,r,x,y;
while (m--)
{
op = (rnd() % 4) + 1;
l = (rnd() % n) + 1;
r = (rnd() % n) + 1;

if(l > r)   swap(l,r);
if(op == 3)
{
x = (rnd() % (r - l + 1)) + 1;
cout << odt.get_k(l,r,x) << "\n";
}
else
{
x = (rnd() % vmax) + 1;
else if(op == 2)    odt.assign(l,r,x);
else
{
y = (rnd() % vmax) + 1;
cout << odt.sum_pow(l,r,x,y) << "\n";
}
}
}

return 0;
}
``````

``````Node(int _l,int _r = -1,ll _v = 0):l(_l),r(_r),v(_v){}
``````

``````S.insert({i,i,a[i]});
``````

...全文
114 回复 打赏 收藏 转发到动态 举报

857

• 近7日
• 近30日
• 至今

CSDN高校俱乐部是给大家提供技术分享交流的平台，会不定期的给大家分享CSDN方面的相关比赛以及活动或实习报名链接，希望大家一起努力加油！共同建设中南民族大学良好的技术知识分享社区。

1.社区成员不得在社区发布违反社会主义核心价值观的言论。

2.社区成员不得在社区内谈及政治敏感话题。

3.该社区为知识分享的平台，可以相互探讨、交流学习经验，尽量不在社区谈论其他无关话题。