码迷,mamicode.com
首页 > 其他好文 > 详细

Luogu3792 由乃与大母神原型和偶像崇拜

时间:2020-04-30 11:39:02      阅读:43      评论:0      收藏:0      [点我收藏+]

标签:efi   build   一个   www   upd   puts   http   pos   href   

Description

link

看页面最低端即可

Solution

引理:现在有两个正整数集合 \(\{S\},\{T\}\)\(\{S\}\ne \{T\},|S|=|T|\)

则有:\(\sum\limits_{x\in S} 2^x\ne \sum\limits_{y\in T}2^y\)

证明:由二进制考虑,就证完了

然后我们维护上这个区间 \(2\) 的次幂和,和区间 \(min\)\(max\)

在判断区间是不是满足的时候直接 \(min\) \(max\) 等比数列求个和就好了

这个题我并不知道是不是在次方足够大的时候可以直接取 \(x^p\) 就可以满足条件了

(但是据说维护平方和就能过去了?)

需要 \(hash\)

三个模数会挂,\(998244353\) 一个就能过了

Code

#include<bits/stdc++.h>
using namespace std;
#define int long long
#define reg register
namespace yspm{
	inline int read()
	{
		int res=0,f=1; char k;
		while(!isdigit(k=getchar())) if(k==‘-‘) f=-1;
		while(isdigit(k)) res=res*10+k-‘0‘,k=getchar();
		return res*f;
	}
	const int N=5e5+10;
	int mod=998244353,a[N],n,T;
	inline int ksm(int x,int y,int z)
	{
		int res=1; for(;y;y>>=1,(x*=x)%=z) if(y&1) (res*=x)%=z;
		return res;
	}
	inline int add(int x,int y){return x+y>=mod?x+y-mod:x+y;}
	struct node{
		int l,r,sum,minn,maxx;
		#define l(p) t[p].l
		#define r(p) t[p].r
		#define sum(p) t[p].sum
		#define minn(p) t[p].minn
		#define maxx(p) t[p].maxx
	}t[N<<2];
	inline int min(int x,int y){return x<y?x:y;}
	inline int max(int x,int y){return x>y?x:y;}
	inline void push_up(int p)
	{
		minn(p)=min(minn(p<<1),minn(p<<1|1)); 
		maxx(p)=max(maxx(p<<1),maxx(p<<1|1)); 
		sum(p)=add(sum(p<<1),sum(p<<1|1));
		return ;
	}
	inline void build(int p,int l,int r)
	{
		l(p)=l; r(p)=r; 
		if(l==r)
		{
			minn(p)=maxx(p)=a[l];
			sum(p)=ksm(2,a[l],mod);
			return ;
		}
		int mid=(l+r)>>1; 
		build(p<<1,l,mid); build(p<<1|1,mid+1,r);
		return push_up(p);
	}
	inline void update(int p,int x,int d)
	{
		if(l(p)==x&&r(p)==x)
		{
			minn(p)=maxx(p)=d;
			sum(p)=ksm(2,d,mod);
			return ;
		} int mid=(l(p)+r(p))>>1;
		if(x<=mid) update(p<<1,x,d);
		else update(p<<1|1,x,d);
		return push_up(p);
	}
	inline node ask(int p,int l,int r)
	{
		if(l<=l(p)&&r(p)<=r) return t[p];
		int mid=(l(p)+r(p))>>1;
		if(l>mid) return ask(p<<1|1,l,r);
		if(r<=mid) return ask(p<<1,l,r);
		node ans; node t1=ask(p<<1,l,r),t2=ask(p<<1|1,l,r);
		ans.maxx=max(t1.maxx,t2.maxx); 
		ans.minn=min(t1.minn,t2.minn);
		ans.sum=add(t1.sum,t2.sum);
		return ans;
	}
	signed main()
	{
		n=read(); T=read();
		for(reg int i=1;i<=n;++i) a[i]=read();
		build(1,1,n);
		while(T--)
		{
			int opt=read();
			if(opt==1)
			{
				int pos=read(),val=read();
				update(1,pos,val);	
			}
			else 
			{
				int l=read(),r=read();
				node res=ask(1,l,r); 
				if(res.maxx-res.minn!=r-l){puts("yuanxing"); continue;}
				int tsum=(ksm(2,res.maxx+1,mod)-ksm(2,res.minn,mod)+mod)%mod;
				if(tsum!=res.sum) puts("yuanxing"); 
				else puts("damushen");
			}
		}
		return 0;
	}
}
signed main(){return yspm::main();}

Review

不错的线段树题,把线段树当做工具使用的那种题

Luogu3792 由乃与大母神原型和偶像崇拜

标签:efi   build   一个   www   upd   puts   http   pos   href   

原文地址:https://www.cnblogs.com/yspm/p/12807539.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!