ODT/珂朵莉树

  • \(1\ l\ r\ x\) :对于 \(i\) 满足 \(l \le i \le r\),将 \(a _ i + x\) 赋值给 \(a _ i\)
  • \(2\ l\ r\ x\) :对于 \(i\) 满足 \(l \le i \le r\),将 \(x\) 赋值给 \(a _ i\)
  • \(3\ l\ r\ x\) :输出范围 \([l, r]\) 中第 \(x\) 小的数字,即在所有满足 \(l \le i \le r\)\(a _ i\) 排序后第 \(x\) 小的数字。保证 \(1 \le x \le r - l + 1\)
  • \(4\ l\ r\ x\ y\) :输出范围 \([l, r]\) 中所有 \(a _ i\)\(x\) 次幂之和模 \(y\),即 \(\left( \sum _ {i = l} ^ r {a _ i} ^ x \right) \bmod y\)
#include<bits/stdc++.h>
#define int long long
#define ins insert
#define er erase
#define lb lower_bound
#define ub upper_bound
#define be begin
#define sit set<_>::iterator
#define fi first
#define se second
#define pb push_back
using namespace std;
constexpr int maxn=5e5+10,p=1e9+7;
int read()
{
    int x=0,f=1;
    char ch=getchar();
    while (ch<'0' || ch>'9')
    {
        if (ch == '-') f=-1;
        ch=getchar();
    }
    while (ch>='0' && ch<='9')
    {
        x=(x<<1)+(x<<3)+ch-'0';
        ch=getchar();
    }
    return x*f;
}
int n,m,seed,vm;
int a[maxn];
int rnd()
{
	int res=seed;
	seed=(seed*7+13)%p;
	return res;
}
struct _
{
    mutable int l,r,v;
    bool operator < (const _ &a) const {return l<a.l;};
};
struct __
{
    int v,len;
    bool operator < (const __ &a) const {return v<a.v;}
};
set<_> st;
sit split(int x)
{
    sit it=st.lb({x,0,0});
    if (it!=st.end() && it->l == x) return it;
    it--;
    if (it->r<x) return st.end();
    int r=it->r,v=it->v;
    it->r=x-1;
    return st.ins({x,r,v}).fi;
}
void add(int l,int r,int v)
{
    sit it2=split(r+1),it1=split(l);
    for (sit i=it1;i!=it2;i++) i->v+=v;
}
void assign(int l,int r,int v)
{
    sit it2=split(r+1),it1=split(l);
    st.er(it1,it2);
    st.ins({l,r,v});
}
int rnk(int l,int r,int k)
{
    sit it2=split(r+1),it1=split(l);
    vector<__> v;
    for (sit i=it1;i!=it2;i++) v.pb({i->v,i->r-i->l+1});
    sort(v.begin(),v.end());
    int i;
    for (i=0;i<v.size();i++)
    {
        if (k>v[i].len) k-=v[i].len;
        else break;
    }
    return v[i].v;
}
int power(int x,int y,int mo)
{
    int res=1;
    x%=mo;
    while (y)
    {
        if (y&1) (res*=x)%=mo;
        (x*=x)%=mo;
        y>>=1;
    }
    return res;
}
int calc(int l,int r,int x,int y)
{
    sit it2=split(r+1),it1=split(l);
    int ans=0;
    for (sit i=it1;i!=it2;i++) (ans+=power(i->v,x,y)*(i->r-i->l+1)%y)%=y;
    return ans;
}
signed main()
{
    n=read(),m=read(),seed=read(),vm=read();
    for (int i=1;i<=n;i++)
	{
		a[i]=(rnd()%vm)+1;
        st.ins({i,i,a[i]});
	}
    for (int i=1;i<=m;i++)
	{
	    int x=0,y=0;
		int op=(rnd()%4)+1;
		int l=(rnd()%n)+1;
		int r=(rnd()%n)+1;
		if (l>r) swap(l,r);
		if (op == 3) x=(rnd()%(r-l+1))+1;
		else x=(rnd()%vm)+1;
		if (op == 4) y=(rnd()%vm)+1;
		if (op == 1) add(l,r,x);
		else if (op == 2) assign(l,r,x);
		else if (op == 3) printf("%lld\n",rnk(l,r,x));
		else printf("%lld\n",calc(l,r,x,y));
	}
    return 0;
}
posted @ 2026-06-27 14:50  msjing  阅读(4)  评论(0)    收藏  举报