[TJOI2018]数学计算

解析:只要离线一下,对于每种操作1算一下它产生贡献的区间就行了,那么这个直接线段树维护

#include<bits/stdc++.h>
using namespace std;
const int MAXN=1e5+10;
int T,n,opt,l[MAXN];
long long mod,m,q[MAXN],f[MAXN<<2];
void pushdown(int k){
	if (f[k]!=1) 
	{
		f[k<<1]=(f[k<<1]*f[k])%mod; f[k<<1|1]=f[k<<1|1]*f[k]%mod; f[k]=1;
	}
}
void change(int l,int r,int k,int ll,int rr,long long t)
{
	if (l==ll&&r==rr)
	{
		f[k]=(f[k]*t)%mod;
	}
	else {
		int mid=(l+r)/2;
		pushdown(k);
		if (rr<=mid) change(l,mid,k<<1,ll,rr,t); else if (ll>mid) change(mid+1,r,k<<1|1,ll,rr,t);
		else  {
			change(l,mid,k<<1,ll,mid,t); change(mid+1,r,k<<1|1,mid+1,rr,t);
		}
	}
}
void pri(int l,int r,int k)
{
    if (l==r) printf("%lld\n",f[k]);
    else {
    	int mid=(l+r)/2;
        pushdown(k);
        pri(l,mid,k<<1); pri(mid+1,r,k<<1|1);
    }
}
int main()
{
	scanf("%d",&T);
	while (T--)
	{
		scanf("%d%lld",&n,&mod);
		memset(q,0,sizeof(q));
		memset(l,0,sizeof(l));
		for (int i=1;i<=(n<<2);i++) f[i]=1;
		for (int i=1;i<=n;i++)
		{
             scanf("%d%lld",&opt,&m);
             if (opt==1) q[i]=m%mod; else l[m]=i-1;
		}
		for (int i=1;i<=n;i++)
			if (q[i]){
              change(1,n,1,i,l[i]?l[i]:n,q[i]);
			}
		pri(1,n,1);
	}
}

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值