码迷,mamicode.com
首页 > 其他好文 > 详细

【CF896C】Willem, Chtholly and Seniorious(ODT本源)

时间:2020-06-11 16:16:45      阅读:81      评论:0      收藏:0      [点我收藏+]

标签:++i   操作   assign   begin   ems   cas   iter   reg   iterator   

点此看题面

大致题意: 给定一个序列,支持四种操作:区间加一个值;区间赋值;求区间第\(k\)大;求区间\(x\)次方和模\(y\)的值(\(y\)每次给出)。(数据随机)

前言

区间赋值?数据随机?珂朵莉树!

听说这可是\(ODT\)的本源题啊。。。

\(ODT\)

如果你不知道\(ODT\),可以看我的这篇博客:神奇的暴力数据结构——ODT(珂朵莉树)

考虑如何处理每一个操作:

  • 区间加法:直接暴力枚举修改。
  • 区间赋值:就是\(Assign\)操作。
  • 区间第\(k\)大:把所有区间存下来排个序,然后暴枚找第\(k\)大。
  • 区间\(x\)次方和:直接暴力枚举统计答案。

具体实现详见代码。

代码

#include<bits/stdc++.h>
#define Tp template<typename Ty>
#define Ts template<typename Ty,typename... Ar>
#define Reg register
#define RI Reg int
#define Con const
#define CI Con int&
#define I inline
#define W while
#define N 100000
#define X 1000000007
#define LL long long
#define swap(x,y) (x^=y^=x^=y)
using namespace std;
int n,seed,Mx,a[N+5];I int Rd(CI x) {RI t=seed;return seed=(7LL*seed+13)%X,t%x+1;}
I int QP(RI x,RI y,RI p) {RI t=1;W(y) y&1&&(t=1LL*t*x%p),x=1LL*x*x%p,y>>=1;return t;}
class ChthollyTree//珂朵莉树
{
	private:
		#define IT set<P>::iterator
		#define T insert
		#define E erase
		#define fi first
		#define se second
		struct P
		{
			int l,r;mutable LL v;I P(CI x=0,CI y=0,Con LL& t=0):l(x),r(y),v(t){}
			I bool operator < (Con P& o) Con {return l<o.l;}
		};set<P> S;
		I IT Sp(CI x)//分裂
		{
			IT t=S.lower_bound(P(x));if(t!=S.end()&&t->l==x) return t;
			RI l=(--t)->l,r=t->r;LL v=t->v;return S.E(t),S.T(P(l,x-1,v)),S.T(P(x,r,v)).fi;
		}
	public:
		I void Build() {for(RI i=1;i<=n;++i) S.T(P(i,i,a[i]));}//初始化
		I void A(CI l,CI r,CI v) {IT R=Sp(r+1),L=Sp(l);S.E(L,R),S.T(P(l,r,v));}//推平
		I void U(CI l,CI r,CI v) {IT R=Sp(r+1),L=Sp(l);W(L!=R) (L++)->v+=v;}//区间加法
		vector<pair<LL,int> > v;I LL G(CI l,CI r,RI k)//区间第k大
		{
			IT R=Sp(r+1),L=Sp(l);v.clear();W(L!=R) v.push_back(make_pair(L->v,L->r-L->l+1)),++L;//存下来
			RI i;for(sort(v.begin(),v.end()),i=0;v[i].se<k;k-=v[i++].se);return v[i].fi;//暴枚
		}
		I int Q(CI l,CI r,CI x,CI y)//区间x次方和
		{
			IT R=Sp(r+1),L=Sp(l);RI t=0;W(L!=R)
				t=(1LL*(L->r-L->l+1)*QP(L->v%y,x,y)+t)%y,++L;return t;//暴枚统计答案
		}
}O;
int main()
{
	RI Qt,i;for(scanf("%d%d%d%d",&n,&Qt,&seed,&Mx),i=1;i<=n;++i) a[i]=Rd(Mx);O.Build();
	RI op,l,r,x,y;W(Qt--) switch(op=Rd(4),l=Rd(n),r=Rd(n),l>r&&swap(l,r),op)
	{
		case 1:O.U(l,r,Rd(Mx));break;case 2:O.A(l,r,Rd(Mx));break;
		case 3:printf("%lld\n",O.G(l,r,Rd(r-l+1)));break;
		case 4:x=Rd(Mx),y=Rd(Mx),printf("%d\n",O.Q(l,r,x,y));break;
	}return 0;
}

【CF896C】Willem, Chtholly and Seniorious(ODT本源)

标签:++i   操作   assign   begin   ems   cas   iter   reg   iterator   

原文地址:https://www.cnblogs.com/chenxiaoran666/p/CF896C.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!