codeforces 896C


由于是随机数生成,所以可以用map或者set的平衡树维护。

对于各类操作,暴力即可(看了题解,一口老血吐出来)

注意操作2是,删除后合并即可。


注意如果数在某个区间内,直接map  tree[A] = B ,即new了该结点,

还有注意upper_bound,和lower_bound返回的指针。


#include 

using namespace std;
typedef long long ll;
const int maxn = 150005 ;
ll seed , vmax , n , m;
ll rnd(){
    ll ret = seed ;
    seed = (seed * 7 + 13) % 1000000007 ;
    return ret ;
}

ll Power(ll Base, ll Exp, ll Mod)
{
	Base %= Mod;
	ll res = 1 ;
	do
	{
		if (Exp & 1)
			(res *= Base) %= Mod;
		(Base *= Base) %= Mod;
	}
	while (Exp >>= 1);
	return res;
}

map tree ;

void print(){
    for(auto i = tree.begin() ; i != tree.end() ; i ++ ){
        cout << i->second << " " ;
    }cout << endl ;
}

void initinit(){
    ll temp ;
    for(int i = 1 ; i <= n ; i ++ ){
        temp = (rnd() % vmax) + 1 ;
        tree.insert(tree.end() , make_pair(i , temp)) ;
    }
    tree.insert(tree.end() , make_pair(n + 1 , 0)) ;

    int op , l , r , 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 ;

        ///may l and r between other range
        auto it_l = -- tree.upper_bound(l) ;
        if(it_l->first != l){
            tree[l] = it_l->second ;
            ++ it_l ;
        }
        auto it_r = tree.lower_bound(r + 1) ;
        if(it_r->first != r + 1) {
            -- it_r ;
            tree[r + 1] = it_r->second ;
            ++ it_r ;
        }
        //print() ;
        bool flag = 0 ;
        switch(op){
            static vector > v ;
            static ll res ;

            case 1:
                while(it_l != it_r)
                    (-- it_r)->second += x ;
                break ;
            case 2:
                while(it_l != it_r)
                    tree.erase(it_l ++ ) ;
                tree[l] = x ;
                break ;
            case 3:
                v.clear() ;
                for(int ub ; it_l != it_r ; ){
                    ub = (it_r --)->first ;
                    v.push_back(make_pair
                        (it_r->second, ub - it_r->first)) ;
                }
                sort(v.begin() , v.end()) ;
                for(int i = 0 , cnt = 0 ; ; i ++ ){
                    if(x <= (cnt += v[i].second)){
                        printf("%lld\n" , v[i].first) ;
                        break ;
                    }
                }
                break ;
            case 4:{
                res = 0 ;
                for(int ub ; it_l != it_r ; ) {
                    ub = (it_r --)->first ;
                    res = (res + (Power(it_r->second, x, y) * (ub - it_r->first)) %y ) % y;
                }

                    printf("%lld\n" , res) ;

                break ;
            }
        }
    }
}

int main(){
    scanf("%d %d %lld %d" , &n , &m , &seed , &vmax) ;
    initinit() ;
    return 0 ;
}

你可能感兴趣的:(树,stl,数据结构)