Codeforces Round #449 C. Willem, Chtholly and Seniorious (Old Driver Tree)

http://codeforces.com/problemset/problem/896/C

题意:

对于一个随机序列,执行以下操作:

区间赋值

区间加

区间求第k小

区间求k次幂的和

对于随机序列,可以使用Old Driver Tree

就是将序列中,连续的相同值域合并为一段

然后暴力操作

#include<set>
#include<vector>
#include<cstdio>
#include<iostream>
#include<algorithm>

using namespace std;

typedef long long LL;

#define N 100001

int n,m,seed,vmax,ret;
int a[N];

struct node
{
    int l,r;
    mutable LL val;
    bool operator < (node p) const
    {
        return l<p.l;
    }
    node(int l=0,int r=0,LL val=0):l(l),r(r),val(val) { }
};

set<node>s;

typedef set<node> :: iterator seti;

vector<pair<LL,int> >par;

void read(int &x)
{
    x=0; char c=getchar();
    while(!isdigit(c))  c=getchar(); 
    while(isdigit(c)) { x=x*10+c-'0'; c=getchar(); }    
}

int rnd()
{
    ret=seed;
    seed=((LL)seed*7+13)%1000000007;
    return ret;
}

void split(int pos)
{
    seti it=s.lower_bound(node(pos,-1,-1));
    if(it==s.end() || it->l>pos)
    {
        --it;
        int l=it->l,r=it->r;
        LL val=it->val;
        s.erase(it);
        s.insert(node(l,pos-1,val));
        s.insert(node(pos,r,val));
    }
}

LL quickpow(LL a,LL x,LL mod)
{
    LL res=1;
    for(;x;x>>=1,a=a*a%mod)
        if(x&1) res=res*a%mod;
    return res;
}

int main()
{
    read(n);
    read(m);
    read(seed);
    read(vmax);
    for(int i=1;i<=n;++i) a[i]=rnd()%vmax+1;
    int r;
    for(int i=1;i<=n;)
    {
        r=i+1;
        while(a[r]==a[i]) r++;
        s.insert(node(i,r-1,(LL)a[i]));
        i=r;
    }
    int op,l,x,y;
    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;
        split(l);
        if(r<n) split(r+1);
        seti itl=s.lower_bound(node(l,-1,-1));
        seti itr=s.upper_bound(node(r,-1,-1));
        if(op==1)
        {
            for(seti it=itl;it!=itr;++it) it->val+=x;
        } 
        else if(op==2)
         {
             s.erase(itl,itr);
             s.insert(node(l,r,x));
        }
        else if(op==3)
        {
            par.clear();
            for(seti it=itl;it!=itr;++it) 
                par.push_back(make_pair(it->val,it->r-it->l+1));
            sort(par.begin(),par.end());
            for(int i=0;i<par.size();++i) 
            {
                x-=par[i].second;
                if(x<=0) 
                {
                    cout<<par[i].first<<'
';
                    break;
                }
            }
        }
        else 
        {
            LL ans=0;
            for(seti it=itl;it!=itr;++it)
            {
                LL val=quickpow(it->val%y,x,y);
                val=val*(it->r-it->l+1)%y;
                ans=(ans+val)%y;
            }
            cout<<ans<<'
';
        }
    }
    return 0;
}
C. Willem, Chtholly and Seniorious
time limit per test
2 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output

— Willem...

— What's the matter?

— It seems that there's something wrong with Seniorious...

— I'll have a look...

Seniorious is made by linking special talismans in particular order.

After over 500 years, the carillon is now in bad condition, so Willem decides to examine it thoroughly.

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:

  • l r x: For each i such that l ≤ i ≤ r, assign ai + x to ai.
  • l r x: For each i such that l ≤ i ≤ r, assign x to ai.
  • 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 thatl ≤ i ≤ r are taken and sorted into an array of non-decreasing integers. It's guaranteed that 1 ≤ x ≤ r - l + 1.
  • 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.

Examples
input
10 10 7 9
output
2
1
0
3
input
10 10 9 9
output
1
1
3
3
Note

In the first example, the initial array is {8, 9, 7, 2, 3, 1, 5, 6, 4, 8}.

The operations are:

  • 2 6 7 9
  • 1 3 10 8
  • 4 4 6 2 4
  • 1 4 5 8
  • 2 1 7 1
  • 4 7 9 4 4
  • 1 2 7 9
  • 4 5 8 1 1
  • 2 5 7 5
  • 4 3 10 8 5
原文地址:https://www.cnblogs.com/TheRoadToTheGold/p/8076064.html