求卡常
  • 板块学术版
  • 楼主Harry27182SDream
  • 当前回复3
  • 已保存回复3
  • 发布时间2022/9/6 10:08
  • 上次更新2023/10/27 12:25:46
查看原帖
求卡常
376997
Harry27182SDream楼主2022/9/6 10:08

RT,卡了一上午了,实在卡不动了,按理说是可以过的,n,q5×105n,q\leq 5\times10^5,时间复杂度 O(27qlogn)O(27qlogn),算出来在 2e8-3e8 之间,时限 1.5s,求助/kel

#include<bits/stdc++.h>
#pragma GCC optimize(2)
#define int long long
using namespace std;
struct matrix
{   
    int x,y,data[5][5],val;
    matrix ()
    {
    	x=0;y=0;val=0;
    	memset(data,0,sizeof(data));
	}
}tr[2000005];
int T,n,q,ta,tb,A,B,wa,wb,x,l,r,op,pb[500005],pa[500005];
const int mod=998244353;
int read()
{ 
	int x=0;char s=getchar();
	while(s<'0'||s>'9')s=getchar();
	while(s>='0'&&s<='9'){x=(x<<3)+(x<<1)+s-'0';s=getchar();}
	return x;
}
int power(int x,int y)
{
	int res=1;
	while(y)
	{
		if(y&1)res=res*x%mod;
		y/=2;x=x*x%mod;
	}
	return res;
}
matrix operator * (matrix a,matrix b)
{
	matrix c;
	for(int i=1;i<=a.x;i++)
	{
		for(int j=1;j<=b.y;j++)
		{
			if(a.data[i][1]&&b.data[1][j])c.data[i][j]=(c.data[i][j]+a.data[i][1]*b.data[1][j])%mod;
			if(a.data[i][2]&&b.data[2][j])c.data[i][j]=(c.data[i][j]+a.data[i][2]*b.data[2][j])%mod;
			if(a.data[i][3]&&b.data[3][j])c.data[i][j]=(c.data[i][j]+a.data[i][3]*b.data[3][j])%mod;
		}
	}
	c.x=a.x;c.y=b.y;c.val=(a.val+b.val)%mod;
	return c;
}
matrix newcode(int k)
{
	matrix a;
	a.x=a.y=3;a.val=pa[k]*power(pb[k],mod-2)%mod;
	a.data[1][1]=(ta*power(tb,mod-2)%mod*(pb[k]-pa[k])%mod*power(pb[k],mod-2)%mod+pa[k]*power(pb[k],mod-2)%mod)%mod;
	a.data[1][2]=a.data[3][1]=a.data[3][2]=pa[k]*power(pb[k],mod-2)%mod;
	a.data[2][2]=a.data[3][3]=1;
	return a;
}
void build(int k,int l,int r)
{
	if(l==r){tr[k]=newcode(l);return;}
	int mid=(l+r)>>1;
	build(k<<1,l,mid);
	build(k<<1|1,mid+1,r);
	tr[k]=tr[k<<1]*tr[k<<1|1]; 
}
void change(int k,int l,int r,int x)
{
	if(l==r){tr[k]=newcode(x);return;}
	int mid=(l+r)>>1;
	if(x<=mid)change(k<<1,l,mid,x);
	else change(k<<1|1,mid+1,r,x);
	tr[k]=tr[k<<1]*tr[k<<1|1]; 
}
matrix query(int k,int l,int r,int x,int y)
{
	if(x<=l&&r<=y)return tr[k];
	int mid=(l+r)>>1;
	if(y<=mid)return query(k<<1,l,mid,x,y);
	else if(x>mid)return query(k<<1|1,mid+1,r,x,y);
	else return query(k<<1,l,mid,x,y)*query(k<<1|1,mid+1,r,x,y);
}
signed main()
{
	freopen("iiidx.in","r",stdin);
	freopen("iiidx.out","w",stdout);
	T=read();n=read();q=read();ta=read();tb=read();A=read();B=read();
	for(int i=1;i<=n;i++)pa[i]=read(),pb[i]=read();
	build(1,1,n);
	while(q--)
	{
		op=read();
		if(op==0)
		{
			x=read();wa=read();wb=read();
			pa[x]=wa;pb[x]=wb;
			change(1,1,n,x);
		}
		else
		{
			l=read();r=read();
			if(l==r){printf("%lld\n",(A+B)*pa[l]%mod*power(pb[l],mod-2)%mod);continue;}
			matrix res=query(1,1,n,l+1,r);
			int ans=A*(pa[l]*power(pb[l],mod-2)%mod+res.val)%mod;
			matrix base;
			base.x=1;base.y=3;
			base.data[1][1]=base.data[1][2]=pa[l]*power(pb[l],mod-2)%mod;base.data[1][3]=1;
			ans=(ans+B*(base*res).data[1][2]%mod)%mod;
			printf("%lld\n",ans);
		}
	}
	return 0;
}
2022/9/6 10:08
加载中...