Uoj #218. 【UNR #1】火车管理 可持久化线段树+思维

Code:

#include<bits/stdc++.h>
#define maxn 500005   
using namespace std;
int n,Q,ty,lastans=0; 
int rt[maxn], tim[maxn], lp[maxn], tp[maxn];     
void setIO(string s)
{
	string in=s+".in"; 
	string out=s+".out"; 
	freopen(in.c_str(),"r",stdin); 
	freopen(out.c_str(),"w",stdout);     
}
namespace tree1
{
	#define lson ( x<<1)
	#define rson ( (x<<1)|1)      
	int sumv[500005<<2],lazy[500005<<2];        
	void mark(int l,int r,int x,int k)
	{
		sumv[x]=(r-l+1)*k; 
		lazy[x]=k; 
	}
	void pushup(int x)
	{
		sumv[x]=sumv[lson]+sumv[rson]; 
	}
	void pushdown(int l,int r,int x)
	{
		if(!lazy[x]) return; 
		int mid=(l+r)>>1; 
		if(mid >= l) mark(l, mid, lson, lazy[x]); 
		if(r > mid) mark(mid + 1, r, rson, lazy[x]);     
		lazy[x]=0;     
	}
	void update(int l,int r,int x,int L,int R,int k)
	{
		if(l>=L&&r<=R)      
		{
			mark(l,r,x,k); 
			return; 
		}
		pushdown(l,r,x); 
		int mid=(l+r)>>1; 
		if(L<=mid) update(l,mid,lson,L,R,k); 
		if(R>mid) update(mid+1,r,rson,L,R,k); 
		pushup(x); 
	} 
	int query(int l,int r,int x,int L,int R)
	{
		if(l>=L&&r<=R) return sumv[x]; 
		pushdown(l, r, x); 
		int mid=(l+r)>>1, tmp=0; 
		if(L<=mid) tmp+=query(l,mid,lson,L,R); 
		if(R>mid) tmp+=query(mid+1,r,rson,L,R); 
		return tmp; 
	}
	#undef lson
	#undef rson 
}; 


namespace tree2
{
	int tot=0; 
	int tag[maxn*75],value[maxn*75];          
	int lson[maxn*75],rson[maxn*75];  
	void mark(int x,int delta)
	{
		value[x]=tag[x]=delta; 
		return; 
	}
	void pushdown(int l,int r,int x)
	{
		if(!tag[x]) return; 
		int mid=(l+r)>>1;         
		if(mid>=l && !lson[x]) lson[x]=++tot; 
		if(r > mid && !rson[x]) rson[x]=++tot;       
		if(lson[x]) mark(lson[x], tag[x]); 
		if(rson[x]) mark(rson[x], tag[x]); 
		tag[x]=0;  
	}        
	void add(int &k,int kk,int l,int r,int L,int R,int delta)
	{
		tag[k=++tot]=0;
		if(l>=L&&r<=R)       
		{
			mark(k, delta); 
			return; 
		}
		int mid=(l+r)>>1; 
		pushdown(l,r,kk); 
		lson[k]=lson[kk], rson[k]=rson[kk];            
		if(L <= mid) add(lson[k], lson[kk], l, mid, L, R, delta); 
		if(R > mid) add(rson[k], rson[kk], mid + 1, r, L, R, delta);      
	}
	int query(int l,int r,int k,int pos)
	{
		if(!k || l == r) return value[k]; 
		pushdown(l,r,k); 
		int mid=(l+r)>>1;
		if(pos<=mid) 
			return query(l,mid,lson[k], pos); 
		else 
			return query(mid+1,r,rson[k],pos); 
	}
}; 
int main()
{    
	// setIO("input"); 
	scanf("%d%d%d",&n,&Q,&ty); 
	int opt,l,r,dd; 	
	for(int i=1;i<=Q;++i) 
	{
		scanf("%d",&opt);    
		switch(opt)
		{
			case 1 : 
			{
				scanf("%d%d",&l,&r);    
				l=(l+lastans*ty)%n+1; 
				r=(r+lastans*ty)%n+1; 
				if(l>r) swap(l,r); 
				lastans=tree1::query(1,n,1,l,r);              
				printf("%d\n",lastans); 
				rt[i]=rt[i-1];          
				break; 
			}
			case 2 : 
			{ 
				scanf("%d",&l);     
				l=(l+lastans*ty)%n+1;  
				int o = tree2::query(1, n, rt[i-1],l);               //查询修改的 l 的修改操作.     
				if(!o) rt[i]=rt[i-1];                   
				else 
				{         
					int oo = tree2::query(1,n,rt[o-1],l);            // 上一次操作   
					tree1::update(1,n,1,l,l,tp[oo]);      //            
					tree2::add(rt[i], rt[i-1], 1, n, l,l,oo);         
				}
				break; 
			}
			case 3 : 
			{
				scanf("%d%d%d",&l,&r,&dd); 
				l=(l+lastans*ty)%n+1; 
				r=(r+lastans*ty)%n+1; 
				if(l>r) swap(l,r);  
				tp[i]=dd; 
				tree1::update(1,n,1,l,r,dd);      
				tree2::add(rt[i],rt[i-1],1,n,l,r,i);                
				break; 
			}
		}
	}
	return 0; 
}

  

猜你喜欢

转载自www.cnblogs.com/guangheli/p/11022707.html