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

来源:互联网 发布:数据库安全性认识 编辑:程序博客网 时间:2024/06/05 18:38

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:

def rnd():

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

for i = 1 to n:

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

for i = 1 to m:

op = (rnd() mod 4) + 1l = (rnd() mod n) + 1r = (rnd() mod n) + 1if (l > r):      swap(l, r)if (op == 3):    x = (rnd() mod (r - l + 1)) + 1else:    x = (rnd() mod vmax) + 1if (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;}
阅读全文
0 0