👉 “Offer 驾到,掘友接招!我正在参与2022春招打卡活动点击查看 活动详情。
珂朵莉树
CF896C Willem, Chtholly and Seniorious
Code
#include<bits/stdc++.h>
using namespace std;
using ll = long long;
inline ll rand(ll& seed) {
ll ret = seed;
seed = (seed * 7 + 13) % 1000000007;
return ret;
}
struct Node {
int l, r;
mutable ll v;
Node(int L, int R = -1, ll val = 0) : l(L), r(R), v(val) {}
bool operator< (const auto& x) const { return l < x.l; }
};
class ODT {
public:
void insert(Node node) {
st.insert(node);
}
auto split(int pos) {
auto it = st.lower_bound( {pos, -1, 0} );
if(it != st.end() and it->l == pos) return it;
it = prev(it);
auto [l, r, val] = *it;
st.erase(it), st.emplace(l, pos - 1, val);
return st.emplace(pos, r, val).first;
}
void assign_val(int l, int r, ll val) {
auto R = split(r + 1), L = split(l);
st.erase(L, R);
st.emplace(l, r, val);
}
void add(int l, int r, ll val) {
auto R = split(r + 1), L = split(l);
for(auto it = L ; it != R; it++ ) {
it->v += val;
}
}
ll rank(int l, int r, ll k) {
vector<pair<ll,int>> v;
auto R = split(r + 1), L = split(l);
for(auto it = L ; it != R; it++) {
v.emplace_back(it->v, it->r - it->l + 1);
}
sort(begin(v), end(v));
for(auto& [val, len] : v) {
k -= len;
if(k <= 0) return val;
}
return 0;
}
ll quick_pow(ll a, ll b, ll mod) {
ll ret = 1; a %= mod;
while(b) {
if(b & 1) ret = ret * a % mod;
a = a * a % mod;
b >>= 1;
}
return ret;
}
ll sum(int l, int r, int ex, int mod) {
auto R = split(r + 1), L = split(l);
ll ret = 0;
for(auto it = L; it != R; it++) {
auto& [L_, R_, val] = *it;
ret = ( ret + 1ll * (R_ - L_ + 1) * quick_pow(val, ex, mod) ) % mod;
}
return ret;
}
private:
set<Node> st;
}odt;
int main() {
ll n, m, seed, M;
scanf("%lld %lld %lld %lld", &n, &m, &seed, &M);
for(int i = 1; i <= n; ++i) {
ll cur = (rand(seed) % M) + 1;
odt.insert( {i, i, cur} );
}
for(int i = 1; i <= m; i++) {
ll opt, l, r, x, y;
opt = (rand(seed) % 4) + 1;
l = (rand(seed) % n) + 1;
r = (rand(seed) % n) + 1;
if(l > r) swap(l, r);
if(opt == 3) {
x = (rand(seed) % (r - l + 1)) + 1;
}else {
x = (rand(seed) % M) + 1;
}
if(opt == 4) {
y = (rand(seed) % M) + 1;
}
if(opt == 1) {
odt.add(l, r, x);
}
else if(opt == 2) odt.assign_val(l, r, x);
else if(opt == 3) printf("%lld\n", odt.rank(l, r, x));
else printf("%lld\n", odt.sum(l, r, x, y));
}
return 0;
}
CF915E Physical Education Lessons
code
//https://codeforces.com/problemset/problem/915/E
#include<bits/stdc++.h>
using namespace std;
struct Node {
int l, r;
mutable int v;
Node(int L, int R = -1, int val = 0) : l(L), r(R), v(val) {}
bool operator< (const auto& x) const { return l < x.l; }
};
int sum = 0;
class ODT {
public:
void insert(Node node) {
st.insert(node);
}
auto split(int pos) {
auto it = st.lower_bound( {pos, -1, 0} );
if(it != st.end() and it->l == pos) return it;
it = prev(it);
auto [l, r, val] = *it;
st.erase(it), st.emplace(l, pos - 1, val);
return st.emplace(pos, r, val).first;
}
void assign_val(int l, int r, int val) {
auto R = split(r + 1), L = split(l);
for(auto it = L; it != R; it++) {
sum -= it->v * (it->r - it->l + 1);
}
st.erase(L, R);
st.emplace(l, r, val);
sum += val * (r - l + 1);
}
private:
set<Node> st;
}odt;
int main() {
int n, m;
scanf("%d %d", &n, &m);
sum = n;
odt.insert( {1, n, 1} );
while(m--) {
int l, r, op;
scanf("%d %d %d", &l, &r, &op);
if(op == 1) {
odt.assign_val(l, r, 0);
}
else {
odt.assign_val(l, r, 1);
}
printf("%d\n", sum);
}
return 0;
}
\