线段树卡T三个点,#7#8#14 有注释,求助
查看原帖
线段树卡T三个点,#7#8#14 有注释,求助
591863
Lofty楼主2023/10/19 09:55
#include<cstdio>
#include<math.h>
#include<cstring>
#include<algorithm>
using namespace std;
#define TP template<typename T>
#define TP_ template<typename T,typename ... T_>
TP void read(T &x)
{
	x=0;int f=0;char ch=getchar();
	for(;ch<'0'||ch>'9';ch=getchar())ch=='-'&&(f=1);
	for(;ch>='0'&&ch<='9';ch=getchar())x=(x<<1)+(x<<3)+(ch^48);
	f&&(x=-x);
}
TP_ void read(T &x,T_&...y){read(x);read(y...);}
TP void write(T x){x<0&&(putchar('-'),x=-x);static int sta[35];int top=0;do{sta[++top]=x%10,x/=10;}while(x);while(top)putchar(sta[top--]^48);}
TP void writeln(const T x){write(x);puts("");}
TP void writesp(const T x){write(x);putchar(32);}
TP_ void writeln(const T x,T_ ...y){writesp(x);writeln(y...);}
using LL=long long;
constexpr int N=2e5+5;
constexpr int P=998244353;
struct trnode
{
	int l,r,lc,rc;
	LL sum,last;
}tr[N<<1];int trlen;
LL a[N];
int n,q;
#define lc tr[now].lc
#define rc tr[now].rc
void pushup(int now)
{
	tr[now].sum=(tr[lc].sum+tr[rc].sum)%P;
}
void pushdown(int now)
{
	if(tr[now].last)
	{
		tr[lc].last+=tr[now].last;
		tr[rc].last+=tr[now].last;
		tr[now].last=0;
	}
}
void build(int l,int r)
{
	int now=++trlen;
	tr[now]={l,r,0,0,0,0};
	if(l==r)tr[now].sum=a[l];
	else
	{
		int mid=(r+l)>>1;
		lc=trlen+1;build(l,mid);
		rc=trlen+1;build(mid+1,r);
		pushup(now);
	}
}
void modify(int now,int l,int r,int c)
{
	if(tr[now].sum==(tr[now].r-tr[now].l+1))return ;//区间全为一,不需要开方和平方
	if(l<=tr[now].l&&tr[now].r<=r&&tr[now].last+c>=0)
	{
		tr[now].last+=c;//这个区间平方 次数加1或减一 
		return ;
	}
	if(tr[now].l==tr[now].r)//没有平方了就直接开方 
	{
		tr[now].sum=sqrt(tr[now].sum);
		return ;
	}
	pushdown(now);
	int mid=(tr[now].r+tr[now].l)>>1;
	if(l<=mid)
		modify(lc,l,r,c);
	if(r>=mid+1)
		modify(rc,l,r,c);
	pushup(now);
}
LL qpow(LL a,LL b,LL p)
{
	LL ans=1%p;a%=p;
	for(;b;b>>=1)
	{
		if(b&1)
			ans=ans*a%p;
		a=a*a%p;
	}
	return ans;
}
void calc(int now)//与上段函数同理 
{
	if(tr[now].sum==(tr[now].r-tr[now].l+1))return ;
	if(tr[now].l==tr[now].r)
	{
		tr[now].sum=qpow(tr[now].sum,qpow(2,tr[now].last,P-1),P);
		return ;
	}
	pushdown(now);
	calc(lc);
	calc(rc);
	pushup(now);
}
int main()
{
	read(n,q);
	for(int i=1;i<=n;i++)
		read(a[i]);
	build(1,n);
	while(q--)//时间复杂度瓶颈在这里的修改 
	{
		int op,l,r;read(op,l,r);
		if(op==1)
			modify(1,l,r,-1);//开方 
		else
			modify(1,l,r,1);//平方 
	}
	calc(1);//最终计算 
	writeln(tr[1].sum);
	return 0;
}

2023/10/19 09:55
加载中...