Codeforces Round #449 (Div. 1) C. Willem, Chtholly and Seniorious

C. Willem, Chtholly and Seniorious
time limit per test2 seconds
memory limit per test256 megabytes
inputstandard input
outputstandard 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:

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:

扫描二维码关注公众号,回复: 2175366 查看本文章

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

题意:给你一个数组,所有处理都是随机的,对于4种操作做对应处理。
做法:emmmm,学到了一个新东西?如果把相同的数作为一个区间,有两种操作:1:将l,r设为一个数,2:把l,r的数都增加c,对于第二种操作就相当于多了两个区间,这样每次遍历所有的区间,复杂度在nlogn左右,,,然后我不知道怎么证明(题解也是这么说QAQ);

#include<bits/stdc++.h>
#define ll long long
#define pii pair<int,ll>
using namespace std;
const int N= 1e5+100;
const int mod= 1e9+7;
int n,m,seed,mn;
int num[N];
map<int,pii> mp;
int rnd(){
    int ret = seed;
    seed = (7LL*seed+13)%mod;
    return ret;
}

ll qpow(int x,int b,int p){
    ll sum = 1;
    ll now = x;
    while(b){
        if(b&1) sum = sum*now%p;
        now = now*now%p;
        b >>= 1;
    }
    return sum;
}

void solve(int op,int l,int r,int x,int y){
    if(op == 1){
        int now = 1;
        while(now <= r){
            pair<int,ll> &tmp = mp[now];
            if(tmp.first >= l){
                if(now < l){
                    mp[l] = tmp;
                    tmp.first = l-1;
                }
                else{
                    if(tmp.first <= r){
                        tmp.second += x;
                    }
                    else{
                        mp[r+1] = tmp;
                        tmp.first = r;
                        tmp.second += x;
                    }
                }
            }
            now = tmp.first+1;
        }
    }
    else if(op == 2){
        int now = 1;
        while(now <= r){
            pair<int,ll> &tmp = mp[now];
            if(tmp.first >= l){
                if(now < l){
                    mp[l] = tmp;
                    tmp.first = l-1;
                }
                while(mp[now].first <= r){
                    now = mp[now].first+1;
                }
                mp[r+1] = mp[now];
                mp[l] = make_pair(r,x);
                now = l;
            }
            now = mp[now].first+1;
        }
    }
    else if(op == 3){
        int now = 1;
        vector<pair<ll,int> > v;
        while(now <= r){
            pair<int,ll> &tmp = mp[now];
            if(tmp.first >= l){
                v.push_back({tmp.second,min(r,tmp.first)-max(l,now)+1});
            }
            now = tmp.first+1;
        }
        sort(v.begin(),v.end());
        int bef = 0;

        for(int i = 0;i < v.size();i ++){
            bef += v[i].second;
            if(bef >= x){
                printf("%lld\n",v[i].first);
                break;
            }
        }
    }
    else if(op == 4){
        ll ans = 0;
        int now = 1;
        while(now <= r){
            pair<int,ll> &tmp = mp[now];
            if(tmp.first >= l){
                ans =(ans+ 1LL*(min(r,tmp.first)-max(l,now)+1)*qpow((int)(tmp.second%y),x,y))%y;
            }
            now = tmp.first+1;
        }
        printf("%lld\n",ans);
    }

}


int main(){
    scanf("%d %d %d %d",&n,&m,&seed,&mn);
    for(int i = 1;i <= n;i ++){
        num[i] = rnd()%mn+1;
        //cout <<i << ' '<< num[i] << endl;
        mp[i] = make_pair(i,num[i]);
    }
    mp[n+1] = make_pair(n+1,0);
    for(int i = 1;i <= m;i ++){
        int op,l,r,x,y=0;
        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()%mn+1;
        if(op == 4) y = rnd()%mn+1;
        //cout<<"!!" <<op << ' '<< l << ' '<< r << ' '<< x << ' '<< y << endl;
        solve(op,l,r,x,y);

    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/zstu_zy/article/details/78709355