ODT求调(玄关)
  • 板块灌水区
  • 楼主GODTREE
  • 当前回复0
  • 已保存回复0
  • 发布时间2024/7/23 10:07
  • 上次更新2024/7/23 10:59:36
查看原帖
ODT求调(玄关)
776799
GODTREE楼主2024/7/23 10:07
#include <bits/stdc++.h>
#define ll long long
using namespace std;
struct odt
{
    ll l,r;
    mutable ll v;
    odt(ll l, ll r = 0, ll v = 0) : l(l), r(r), v(v) {}
    bool operator<(const odt &a) const 
    {
        return l < a.l;
    }
};
set<odt> Chtholly;
ll a[10005],n,m,x,y,op,l,r,vmax,seed;
ll rnd()
{
    ll ret=seed;
    ll seed=(seed*7+13)%1000000007;
    return ret;
}
set<odt>::iterator split(int p)
{
    set<odt>::iterator it=Chtholly.lower_bound(odt(p));//查找p所在的位置
    if (it!=Chtholly.end()&&it->l==p) //p本身就是一个区间的开头
    {
        return it;
    }
    it--;//裂开
    if (it->r<p) return Chtholly.end();
    ll l = it->l;
    ll r = it->r;
    ll v = it->v;
    Chtholly.erase(it);
    Chtholly.insert(odt(l, p-1,v));
    return Chtholly.insert(odt(p,r,v)).first;
}
void add(ll l, ll r, ll x)//添加
{
    set<odt>::iterator itr=split(r+1),itl=split(l);
    for (set<odt>::iterator it = itl;it!=itr;it++) 
    {
        it->v+=x;
    }
}
void assign(ll l,ll r,ll x)//推平
{
    set<odt>::iterator itr=split(r+1),itl=split(l);
    Chtholly.erase(itl,itr);
    Chtholly.insert(odt(l,r,x));
}
int find_k(ll l,ll r,ll x)
{
     set<odt>::iterator itr=split(r+1),itl=split(l);
     int cnt=0;
     set<odt>::iterator i=itl;
     while(cnt<x)
     {
        cnt+=(i->r-i->l+1);
        i++;
     }
     return i->v;
}
ll cal(ll l,ll r,ll x,ll y) 
{
    set<odt>::iterator itr = split(r+1),itl=split(l);
    ll ans = 0;
    for (set<odt>::iterator i = itl; i!=itr;i++)
    {
        int sum=1;
        int p=x,b=i->v;
        while(p>0)
        {
            if(p%2!=0)
            {
                sum=sum*b%y;
            }
            b=b*b%y;
            p/=2;
        }
        sum%=y;
        ans+=sum;
        ans%=y;
    }
    return ans;
}
int main()
{
    cin>>n>>m>>vmax>>seed;
    for (ll i=1;i<=n;i++){a[i]=(rnd()%vmax)+1;}  
	for (ll 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;}
        if (op==1)
        {
            add(l,r,x);
        }
        if (op==2)
        {
            assign(l,r,x);
        }
        if (op==3)
        {
            cout<<find_k(l,r,x)<<endl;
        }
        if (op==4)
        {
            cout<<cal(l,r,x,y)<<endl;
        }
    }
    return 0;
}
2024/7/23 10:07
加载中...