CF 896 C Willem, Chtholly and Seniorious(珂朵莉树模板)

CF 896 C. Willem, Chtholly and Seniorious(珂朵莉树模板)

Problem - C - Codeforces

大意:给出一个区间 , 要求进行四种操作 , 区间加 , 区间第k大 , 区间推平 , 区间求和。

珂朵莉树模板题 , 练手即可。

#include<bits/stdc++.h>
using namespace std;
#define fi first
#define se second
#define IOS std::ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
#define int long long
const int N = 1e5 + 10;
const int mod = 1e9 + 7;
typedef pair<int,int>PII;

struct node{
    
	int l , r;
    mutable int v;
	node(int l , int r = 0 , int v = 0) : l(l), r(r), v(v){}
    bool operator < (const node &a) const {
        return l < a.l;
    }
};

set<node>s;

set<node>::iterator split(int pos){
    set<node>::iterator it = s.lower_bound(node(pos));
    if(it != s.end() && it->l == pos) {
        return it;
    }
    it--;
    if (it->r < pos) return s.end();
    int l = it->l;
    int r = it->r;
    int v = it->v;
    s.erase(it);
    s.insert(node(l , pos - 1 , v));
    return s.insert(node(pos , r , v)).first;
}

inline int qp(int x , int y , int p){
	
	int res = 1 % p;
	x = x % p; 
	while(y){
		if(y & 1) res = res * x % p;
		x = x * x % p;
		y >>= 1;
	}
	return res;
}

void assign(int l , int r , int x) {
    set<node>::iterator itr = split(r + 1) , itl = split(l);
    s.erase(itl , itr);
    s.insert(node(l , r , x));
}

void add(int l , int r , int x){
	set<node>::iterator itr = split(r + 1) , itl = split(l);
	for(auto i = itl ; i != itr ; i ++)  i->v += x;
}

inline int kth(int l , int r , int x){
	vector<PII>v;
	set<node>::iterator itr = split(r + 1) , itl = split(l);
	for(auto i = itl ; i != itr ; i ++) v.emplace_back(i->v , i->r - i->l + 1);
	sort(v.begin() , v.end());
	for(auto [val , num] : v){
		if(x > num) x -= num;
		else return val;
	}
}

inline int sum(int l , int r , int x , int p){
	int res = 0;
	set<node>::iterator itr = split(r + 1) , itl = split(l);
	for(auto i = itl ; i != itr ; i ++){
		res = (res + qp(i->v , x , p) * (i->r - i->l + 1) % p) % p;
	}
	return res;
}

int n , m , seed , vmax , op , a[N] , x , y , l , r;

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

signed main(){

	IOS
	cin >> n >> m >> seed >> vmax;
	for(int i = 1 ; i <= n ; i ++){
		a[i] = (rnd() % vmax) + 1;
		s.insert(node{i , i , a[i]});
	}
	for(int i = 1 ; i <= m ; i ++){
		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;
		}else{
			x = rnd() % vmax + 1;
		}
		if(op == 4) y = rnd() % vmax + 1;
		if(op == 1) add(l , r , x);
		if(op == 2) assign(l , r , x);
		if(op == 3) cout << kth(l , r , x) << "\n";
		if(op == 4) cout << sum(l , r , x , y) << "\n";
	}

	return 0;
}
//freopen("文件名.in","r",stdin);
//freopen("文件名.out","w",stdout);
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

梦里再与你相见

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值