zoukankan      html  css  js  c++  java
  • #珂朵莉树#CF896C Willem, Chtholly and Seniorious

    题目

    支持区间加,区间推平,询问区间第(k)小,
    以及询问区间(sum{a_i^x}pmod y),数据随机


    分析

    由于数据随机,那么区间推平的概率为(frac{1}{4})
    考虑用珂朵莉树实现,用(STL::set)装下相同元素段,
    对于取出一段区间,分离左右端点,直接修改即可


    代码

    #include <cstdio>
    #include <cctype>
    #include <set>
    #include <algorithm>
    #define rr register
    using namespace std;
    typedef long long lll; 
    struct rec{
    	int l,r; mutable lll w;
    	inline bool operator <(const rec &t)const{
    	    return l<t.l;
    	}
    };
    struct Two{
        lll w; int len;
        inline bool operator <(const Two &t)const{
    	    return w<t.w;
    	}
    }b[100011]; 
    typedef set<rec>::iterator ir; ir it0,it1,it;
    set<rec>K; int n,m,seed,mx,mod;
    inline void print(lll ans){
    	if (ans>9) print(ans/10);
    	putchar(ans%10+48);
    }
    inline signed Get(){
    	rr int ans=seed;
    	seed=(7ll*seed+13)%1000000007;
    	return ans;
    }
    inline lll ksm(lll x,lll y,lll p){
    	rr lll ans=1;
    	for (;y;y>>=1,x=x*x%p)
    	    if (y&1) ans=ans*x%p;
    	return ans;
    }
    inline ir Split(int x){
    	it=K.lower_bound((rec){x,0,0});
    	if (it!=K.end()&&it->l==x) return it;
    	rr rec t=*(--it); K.erase(it);
    	K.insert((rec){t.l,x-1,t.w});
    	return K.insert((rec){x,t.r,t.w}).first;
    }
    inline void Assign(int l,int r,int w){
    	it1=Split(r+1),it0=Split(l);
    	K.erase(it0,it1);
    	K.insert((rec){l,r,w});
    }
    signed main(){
    	scanf("%d%d%d%d",&n,&m,&seed,&mx);
    	for (rr int i=1;i<=n;++i)
    		K.insert((rec){i,i,Get()%mx+1});
    	K.insert((rec){n+1,n+1,0});
    	for (rr int i=1;i<=m;++i){
    		rr int opt=Get()%4+1,l=Get()%n+1,r=Get()%n+1;
    		if (l>r) l^=r,r^=l,l^=r;
    		switch (opt){
    			case 1:{
    				rr int x=Get()%mx+1;
    				it1=Split(r+1),it0=Split(l);
    				for (;it0!=it1;++it0) it0->w+=x;
    				break;
    			}
    			case 2:{
    				rr int x=Get()%mx+1;
    				Assign(l,r,x);
    				break;
    			}
    			case 3:{
    				rr int kth=Get()%(r-l+1)+1,tot=0;
    				it1=Split(r+1),it0=Split(l);
    				for (;it0!=it1;++it0){
    					rr rec t=*it0;
    					b[++tot]=(Two){t.w,t.r-t.l+1};
    				}
    				sort(b+1,b+1+tot);
    				for (rr int i=1;i<=tot;++i){
    					kth-=b[i].len;
    					if (kth<=0) {print(b[i].w),putchar(10); break;}
    				}
    				break;
    			}
    			case 4:{
    				rr int y=Get()%mx+1,mod=Get()%mx+1; rr lll ans=0;
    				it1=Split(r+1),it0=Split(l);
    				for (;it0!=it1;++it0){
    					rr rec t=*it0;
    					ans=(ans+ksm(t.w,y,mod)*(t.r-t.l+1)%mod)%mod;
    				}
    				print(ans),putchar(10);
    				break;
    			}
    		}
    	}
    	return 0;
    } 
    
  • 相关阅读:
    使用Python进行文件操作
    Python学习笔记(六)Python组合数据类型
    python基本算法题(一)
    Python要如何实现(列表)排序?
    Python中输入和输出(打印)数据
    Python学习笔记(五)函数和代码复用
    关于Python缩进,我们该了解哪些?
    Python学习笔记(四)Python程序的控制结构
    Python学习笔记(三)字符串类型及其操作(2)
    Java视频按帧保存为图片
  • 原文地址:https://www.cnblogs.com/Spare-No-Effort/p/15179363.html
Copyright © 2011-2022 走看看