【ODT】cf896C - Willem, Chtholly and Seniorious

仿佛没用过std::set

Seniorious has n pieces of talisman. Willem puts them in a line, the i-th of which is an integer ai.

In order to maintain it, Willem needs to perform m operations.

There are four types of operations:

  • 1 l r x: For each i such that l ≤ i ≤ r, assign ai + x to ai.
  • 2 l r x: For each i such that l ≤ i ≤ r, assign x to ai.
  • 3 l r x: Print the x-th smallest number in the index range [l, r], i.e. the element at the x-th position if all the elements ai such that l ≤ i ≤ r are taken and sorted into an array of non-decreasing integers. It's guaranteed that 1 ≤ x ≤ r - l + 1.
  • 4 l r x y: Print the sum of the x-th power of ai such that l ≤ i ≤ r, modulo y, i.e. .

Input

The only line contains four integers n, m, seed, vmax (1 ≤ n, m ≤ 105, 0 ≤ seed < 109 + 7, 1 ≤ vmax ≤ 109).

The initial values and operations are generated using following pseudo code:


def rnd():

ret = seed
seed = (seed * 7 + 13) mod 1000000007
return ret

for i = 1 to n:

a[i] = (rnd() mod vmax) + 1

for i = 1 to m:

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

Here op is the type of the operation mentioned in the legend.

Output

For each operation of types 3 or 4, output a line containing the answer.


 

题目分析

ODT的入门例题。

ODT实际上是将区间缩成点,用平衡树来维护区间的过程。这个东西的“复杂度”只能够依赖于数据随机。

具体可以参考:【毒瘤Warning】Chtholly Tree珂朵莉树详解

  1 #include<bits/stdc++.h>
  2 typedef long long ll;
  3 const int maxn = 100035;
  4 
  5 struct node
  6 {
  7     int l,r;
  8     mutable ll val;
  9     node(int a=0, int b=0, ll c=0):l(a),r(b),val(c) {}
 10     bool operator < (node a) const
 11     {
 12         return l < a.l;
 13     }
 14 };
 15 typedef std::set<node>::iterator itr;
 16 int n,m,p,seed,vmax,a[maxn];
 17 std::set<node> s;
 18 
 19 int rand()
 20 {
 21     int ret = seed;
 22     seed = (seed*7ll+13)%1000000007;
 23     return ret;
 24 }
 25 ll qmi(ll a, ll b)
 26 {
 27     ll ret = 1;
 28     for (a%=p; b; b>>=1,a=1ll*a*a%p)
 29         if (b&1) ret = 1ll*ret*a%p;
 30     return ret;
 31 }
 32 itr split(int pos)
 33 {
 34     itr loc = s.lower_bound(node(pos));
 35     if (loc!=s.end()&&(*loc).l==pos) return loc;
 36     --loc;
 37     int l = (*loc).l, r = (*loc).r;
 38     ll val = (*loc).val;
 39     s.erase(loc);
 40     s.insert(node(l, pos-1, val));
 41     return s.insert(node(pos, r, val)).first;
 42 }
 43 void merge(int l, int r, int val)
 44 {
 45     itr rpos = split(r+1), lpos = split(l);
 46     s.erase(lpos, rpos);
 47     s.insert(node(l, r, val));
 48 }
 49 void modify(int l, int r, int val)
 50 {
 51     itr rpos = split(r+1), lpos = split(l);
 52     for (; lpos!=rpos; ++lpos) (*lpos).val += val;
 53 }
 54 ll getRank(int l, int r, int k)
 55 {
 56     itr rpos = split(r+1), lpos = split(l);
 57     std::vector<std::pair<ll, int> > mp;
 58     for (; lpos!=rpos; ++lpos)
 59         mp.push_back(std::make_pair((*lpos).val, (*lpos).r-(*lpos).l+1));
 60     std::sort(mp.begin(), mp.end());
 61     for (int i=0,mx=mp.size(); i<mx; i++)
 62     {
 63         k -= mp[i].second;
 64         if (k <= 0) return mp[i].first;
 65     }
 66     return -1;
 67 }
 68 int calc(int l, int r, int x)
 69 {
 70     int ret = 0;
 71     itr rpos = split(r+1), lpos = split(l);
 72     for (; lpos!=rpos; ++lpos)
 73         ret = (ret+1ll*qmi((*lpos).val, x)*((*lpos).r-(*lpos).l+1)%p)%p;
 74     return ret;
 75 }
 76 int main()
 77 {
 78     scanf("%d%d%d%d",&n,&m,&seed,&vmax);
 79     for (int i=1; i<=n; i++)
 80     {
 81         a[i] = rand()%vmax+1;
 82         s.insert(node(i, i, a[i]));
 83     }
 84     s.insert(node(n+1, n+1, 0));
 85     for (int i=1,x; i<=m; i++)
 86     {
 87         int opt = rand()%4+1, l = rand()%n+1, r = rand()%n+1;
 88         if (l > r) std::swap(l, r);
 89         if (opt==3) x = rand()%(r-l+1)+1;
 90         else x = (rand()%vmax)+1;
 91         if (opt==1) modify(l, r, x);
 92         else if (opt==2) merge(l, r, x);
 93         else if (opt==3) printf("%lld\n",getRank(l, r, x));
 94         else{
 95             p = rand()%vmax+1;
 96             printf("%d\n",calc(l, r, x));
 97         }
 98     }
 99     return 0;
100 }

 

 

 

 

END

posted @ 2019-04-03 21:27  AntiQuality  阅读(211)  评论(0编辑  收藏  举报