暴力数据结构-珂朵莉树
珂朵莉树模板
一种使用std:set维护区间问题的暴力数据结构, 当数据足够随机时有良好的表现
缺点: 可能会被特殊数据卡成暴力的复杂度
基本操作 :split() //返回指定位置的迭代器
assign() 区间推平
板子:
struct Node{ //珂朵莉树基本结构
int l, r;
mutable LL val;
Node(int l_ = -1, int r_ = -1, LL val_ = 0){
l = l_; r = r_; val = val_;
}
bool operator < (const Node& t) const{
return l < t.l;
}
};
IT split(int pos){ //split操作
IT it = St.lower_bound(Node(pos));
if(it!=St.end() && it->l == pos) return it;
it--;
Node tmp = *it;
St.erase(it);
St.insert(Node(tmp.l, pos - 1, tmp.val));
return St.insert(Node(pos, tmp.r, tmp.val)).first;
}
void assign(int l, int r, LL val){ //区间推平操作
IT itr = split(r + 1), itl = split(l);
St.erase(itl, itr);
St.insert(Node(l, r, val));
}
#include<bits/stdc++.h>
using namespace std;
#define mod %
typedef long long LL;
LL a[100010];
int n, m; LL seed, vmax;
struct Node{
int l, r;
mutable LL val;
Node(int l_ = -1, int r_ = -1, LL val_ = 0){
l = l_; r = r_; val = val_;
}
bool operator < (const Node& t) const{
return l < t.l;
}
};
set<Node> St;
typedef set<Node>::iterator IT;
IT split(int pos){
IT it = St.lower_bound(Node(pos));
if(it!=St.end() && it->l == pos) return it;
it--;
Node tmp = *it;
St.erase(it);
St.insert(Node(tmp.l, pos - 1, tmp.val));
return St.insert(Node(pos, tmp.r, tmp.val)).first;
}
void assign(int l, int r, LL val){
IT itr = split(r + 1), itl = split(l);
St.erase(itl, itr);
St.insert(Node(l, r, val));
}
void add(int l, int r, LL val){
IT itr = split(r + 1), itl = split(l);
for(IT it = itl; it != itr; it++) it->val += val;
}
LL ksm(LL a, LL b, LL m){
LL res = 1;
while(b){
if(b & 1) res = res * a % m;
b >>= 1;
a = a * a % m;
}
return res;
}
LL query(int l, int r, LL x, LL y){
IT itr = split(r + 1), itl = split(l);
LL res = 0;
for(IT it = itl; it != itr; it++) res = (res + ksm(it->val % y, x, y) % y * (it->r - it->l + 1) % y )% y;
return res ;
}
LL findkth(int l, int r, int k){
vector<pair<LL, int>> v;
IT itr = split(r + 1), itl = split(l);
for(IT it = itl; it != itr; it++) v.push_back({it->val, it->r - it-> l+ 1});
sort(v.begin(), v.end());
for(auto item : v){
k -= item.second;
if(k <= 0) return item.first;
}
return 0;
}
LL rnd(){
LL ret = seed;
seed = (seed * 7 + 13) % 1000000007;
return ret;
}
int main(){
cin >> n >> m >> seed >> vmax;
for(int i = 1; i <= n; i++){
a[i] = (rnd() % vmax) + 1;
}
// for(int i = 1; i <= n; i++) cout << a[i] << ' ';
// cout << endl;
int L, R, V;
L = R = -1;
for(int i = 1; i <= n; i++){
if(L == -1 && R == -1) {
L = i, R = i, V = a[i];
}
if(a[i] == V) R = i;
else{
St.insert(Node(L, R, V));
L = R = i;
V = a[i];
}
}
St.insert(Node(L, R, V));
LL op, l, r, x, y;
for(int i = 1; i <= m; i++){
op = (rnd() mod 4) + 1;
l = (rnd() mod n) + 1;
r = (rnd() mod n) + 1;
if (l > r)
swap(l, r);
if (op == 3)
x = (rnd() mod (r - l + 1)) + 1;
else
x = (rnd() mod vmax) + 1;
if (op == 4)
y = (rnd() mod vmax) + 1;
if(op == 1) add(l, r, x);
else if(op == 2) assign(l, r, x);
else if(op == 3) cout << findkth(l, r, x) << '\n';
else cout << query(l, r, x, y) << '\n';
}
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步