ODT (Old Driver Tree)珂朵莉树
Posted leesongt
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ODT (Old Driver Tree)珂朵莉树相关的知识,希望对你有一定的参考价值。
1 #include <bits/stdc++.h> 2 using namespace std; 3 4 typedef long long LL; 5 const int MOD7 = 1e9 + 7; 6 const int MOD9 = 1e9 + 9; 7 const int imax_n = 1e5 + 7; 8 LL add(LL a, LL b, LL mod) 9 { 10 LL res = 0; 11 LL ans = a; 12 while (b) 13 { 14 if (b&1) res = (res + ans) % mod; 15 ans = (ans + ans) % mod; 16 b>>=1; 17 } 18 return res; 19 } 20 21 LL pow(LL a, LL b, LL mod) 22 { 23 LL res = 1; 24 LL ans = a % mod; 25 while (b) 26 { 27 if (b&1) res = res * ans % mod; 28 ans = ans * ans % mod; 29 b>>=1; 30 } 31 return res; 32 } 33 34 struct node { 35 int l,r; 36 mutable LL v; 37 node(int L, int R=-1, LL V=0):l(L), r(R), v(V){} 38 bool operator<(const node& o) const { 39 return l < o.l; 40 } 41 }; 42 43 set<node> s; 44 45 set<node>::iterator split(int pos) 46 { 47 auto it = s.lower_bound(node(pos)); 48 if (it != s.end() && it->l == pos) return it; 49 --it; 50 if (pos > it->r) return s.end(); 51 int L = it->l, R = it->r; 52 LL V = it->v; 53 s.erase(it); 54 s.insert(node(L, pos-1, V)); 55 return s.insert(node(pos, R, V)).first; 56 // pair<iterator, bool> insert(const value_type& val); 57 } 58 59 void add(int l, int r, LL val=1) 60 { 61 split(l); 62 auto itr = split(r+1), itl = split(l); 63 for (; itl != itr; ++itl) itl->v += val; 64 } 65 66 void assign_val(int l, int r, LL val=0) 67 { 68 split(l); 69 auto itr = split(r+1), itl = split(l); 70 s.erase(itl, itr); 71 s.insert(node(l, r, val)); 72 } 73 74 LL rank_(int l, int r, int k, bool reversed=0) 75 { 76 vector<pair<LL, int>> vp; 77 if (reversed) k = r - l + 2 - k; 78 split(l); 79 auto itr = split(r+1), itl = split(l); 80 vp.clear(); 81 for (; itl != itr; ++itl) 82 vp.push_back({itl->v, itl->r - itl->l + 1}); 83 sort(vp.begin(), vp.end()); 84 for (auto i: vp) 85 { 86 k -= i.second; 87 if (k <= 0) return i.first; 88 } 89 return -1LL; 90 } 91 92 LL sum(int l, int r, int ex, int mod) 93 { 94 split(l); 95 auto itr = split(r+1), itl = split(l); 96 LL res = 0; 97 for (; itl != itr; ++itl) 98 res = (res + (LL)(itl->r - itl->l + 1) * pow(itl->v, LL(ex), LL(mod))) % mod; 99 return res; 100 } 101 102 int n, m; 103 LL seed, vmax; 104 105 LL rnd() 106 { 107 LL ret = seed; 108 seed = (seed * 7 + 13) % MOD7; 109 return ret; 110 } 111 112 LL a[imax_n]; 113 114 int main() 115 { 116 cin>>n>>m>>seed>>vmax; 117 for (int i=1;i<=n;++i) 118 { 119 a[i] = (rnd() % vmax) + 1; 120 s.insert(node(i,i,a[i])); 121 } 122 s.insert(node(n+1, n+1, 0)); 123 int lines = 0; 124 for (int i =1; i <= m; ++i) 125 { 126 int op = int(rnd() % 4) + 1; 127 int l = int(rnd() % n) + 1; 128 int r = int(rnd() % n) + 1; 129 if (l > r) 130 swap(l,r); 131 int x, y; 132 // cout<<i<<" op = "<<op<<" "; 133 if (op == 3) 134 x = int(rnd() % (r-l+1)) + 1; 135 else 136 x = int(rnd() % vmax) +1; 137 138 if (op == 4) 139 y = int(rnd() % vmax) + 1; 140 if (op == 1) 141 add(l, r, LL(x)); 142 else if (op == 2) 143 assign_val(l, r, LL(x)); 144 else if (op == 3) 145 { 146 // cout<<"lines"<<++lines<<endl; 147 cout<<rank_(l, r, x)<<endl; 148 } 149 else 150 { 151 // cout<<"lines"<<++lines<<endl; 152 cout<<sum(l, r, x, y)<<endl; 153 } 154 } 155 return 0; 156 }
以上是关于ODT (Old Driver Tree)珂朵莉树的主要内容,如果未能解决你的问题,请参考以下文章
[Codeforces896C] Willem, Chtholly and Seniorious (ODT-珂朵莉树)