bzoj 5334 数学计算

bzoj 5334 数学计算

  • 开始想直接模拟过程做,但模数 (M) 不一定为质数,若没有逆元就 (fAKe) 掉了.
  • 注意到操作 (2) 是删除对应的操作 (1) ,相当于只有 (1) 操作,但每个操作有一个生效的时限.
  • 将所有操作离线下来,用一颗线段树维护每个时间的答案.对于操作 (1) ,预处理出生效的时限后,区间修改那一段即可.注意有没有删除的情况,右端点设为 (Q) .
  • 预处理结束后,对每个操作可以一边改一边做,后面的操作显然不会对这里的答案造成影响.
  • 时间复杂度为 (O(QlogQ)) .

原来这东西是叫线段树分治.之前我就叫做是离线后线段树上乱搞...

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define mp make_pair
#define pii pair<int,int>
inline int read()
{
	int out=0,sgn=1;
	char jp=getchar();
	while(jp!='-' && (jp<'0' || jp>'9'))
		jp=getchar();
	if(jp=='-')
		sgn=-1,jp=getchar();
	while(jp>='0' && jp<='9')
		out=out*10+jp-'0',jp=getchar();
	return out*sgn;
}
const int MAXN=1e5+10;
int Q,P;
inline int mul(int a,int b)
{
	return 1LL * a * b % P;
}
int fpow(int a,int b)
{
	int res=1;
	while(b)
		{
			if(b&1)
				res=mul(res,a);
			a=mul(a,a);
			b>>=1;
		}
	return res%P;
}
struct query{
	int op,m,r;
}q[MAXN];
namespace SEG{
	struct node{
		int l,r;
		int prod,tag;
	}Tree[MAXN<<2];
	#define root Tree[o]
	#define lson Tree[o<<1]
	#define rson Tree[o<<1|1]
	void BuildTree(int o,int l,int r)
		{
			root.l=l,root.r=r;
			root.prod=1,root.tag=1;
			if(l==r)
				return;
			int mid=(l+r)>>1;
			BuildTree(o<<1,l,mid);
			BuildTree(o<<1|1,mid+1,r);
		}
	void Modifiy(int o,int v)
		{
			root.prod=mul(root.prod,v);
			root.tag=mul(root.tag,v);
		}
	void pushdown(int o)
		{
			if(root.tag!=1)
				{
					Modifiy(o<<1,root.tag);
					Modifiy(o<<1|1,root.tag);
					root.tag=1;
				}
		}
	void update(int o,int L,int R,int v)
		{
			int l=root.l,r=root.r;
			if(l>R || L>r)
				return;
			if(L<=l && r<=R)
				{
					Modifiy(o,v);
					return;
				}
			pushdown(o);
			update(o<<1,L,R,v);
			update(o<<1|1,L,R,v);
		}
	int query(int o,int pos)
		{
			int l=root.l,r=root.r;
			if(l==r)
				return root.prod;
			if(pos<l || pos>r)
				return 1;
			int mid=(l+r)>>1;
			pushdown(o);
			if(pos<=mid)
				return query(o<<1,pos);
			else
				return query(o<<1|1,pos);
		}
}
int main()
{
	int T=read();
	while(T--)
		{
			Q=read(),P=read();
			for(int i=1;i<=Q;++i)
				{
					int op=read();
					q[i].op=op;
					if(op==1)
						q[i].m=read(),q[i].r=Q+1;
					else
						{
							int pos=read();
							q[pos].r=i;
						}
				}
			SEG::BuildTree(1,1,Q);
			for(int i=1;i<=Q;++i)
				{
					if(q[i].op==1)
						{
							int l=i,r=q[i].r;
							SEG::update(1,l,r-1,q[i].m);
							int ans=SEG::query(1,l);
							printf("%d
",ans);
						}
					else
						{
							int ans=SEG::query(1,i);
							printf("%d
",ans);
						}
				}
		}
	return 0;
}
原文地址:https://www.cnblogs.com/jklover/p/10448242.html