zoukankan      html  css  js  c++  java
  • 洛谷.3792.由乃与大母神原型和偶像崇拜(线段树 数学)

    题目链接

    /*
    平方和公式:用于求连续自然数的平方和 
    ∑(k=1 to n) k^2 = 1^2 + 2^2 +...+ n^2 = n^3/3 + n^2/2 + n/6
    									   = n(n+1)(2n+1)/6
    									   = C(n+2,3)+C(n+1,3)= C(n+1,3)+C(n+1,2)= C(2n+2,3)= nC(n+1,2)-C(n+1,3)
    利用最小值最大值得到[l+1,r]区间平方和:r(r+1)(2r+1)*inv6 - l(l+1)(2l+1)*inv6 
    inv6为%mod下6的逆元,即6^(mod-2)
    注意取模 
    */
    #include<cstdio>
    #include<cctype>
    #include<algorithm>
    #define LL long long
    //#define gc() getchar()
    #define gc() (SS==TT&&(TT=(SS=IN)+fread(IN,1,MAXIN,stdin),SS==TT)?EOF:*SS++)
    const int N=5e5+5,mod=1e9+7,MAXIN=5e6;
    
    int n,q,Maxn,Minn;
    LL inv6;
    char IN[MAXIN],*SS=IN,*TT=IN;
    inline int read()
    {
    	int now=0,f=1;register char c=gc();
    	for(;!isdigit(c);c=gc()) if(c=='-') f=-1;
    	for(;isdigit(c);now=now*10+c-'0',c=gc());
    	return now*f;
    }
    struct Seg_Tree
    {
    	int Min[N<<2],Max[N<<2];
    	LL sum[N<<2];
    	inline void PushUp(int rt)
    	{
    		Min[rt]=std::min(Min[rt<<1],Min[rt<<1|1]);
    		Max[rt]=std::max(Max[rt<<1],Max[rt<<1|1]);
    		sum[rt]=(sum[rt<<1]+sum[rt<<1|1])%mod;
    	}
    	void Build(int l,int r,int rt)
    	{
    		int m=l+r>>1;
    		if(l==r) {Min[rt]=Max[rt]=read(),sum[rt]=1ll*Min[rt]*Min[rt]%mod; return;}
    		Build(l,m,rt<<1),Build(m+1,r,rt<<1|1);
    		PushUp(rt);
    	}
    	void Modify(int l,int r,int rt,int p,int v)
    	{
    		if(l==r) {Max[rt]=Min[rt]=v,sum[rt]=1ll*v*v%mod; return;}
    		int m=l+r>>1;
    		if(p<=m) Modify(l,m,rt<<1,p,v);
    		else Modify(m+1,r,rt<<1|1,p,v);
    		PushUp(rt);
    	}
    	void Query(int l,int r,int rt,int L,int R)
    	{
    		if(L<=l && r<=R)
    		{
    			Maxn=std::max(Maxn,Max[rt]),Minn=std::min(Minn,Min[rt]);
    			return;
    		}
    		int m=l+r>>1;
    		if(L<=m)
    			if(m<R) Query(l,m,rt<<1,L,R),Query(m+1,r,rt<<1|1,L,R);
    			else Query(l,m,rt<<1,L,R);
    		else Query(m+1,r,rt<<1|1,L,R);
    	}
    	LL Query_Sum(int l,int r,int rt,int L,int R)
    	{
    		if(L<=l && r<=R) return sum[rt];
    		int m=l+r>>1;
    		if(L<=m)
    			if(m<R) return (Query_Sum(l,m,rt<<1,L,R)+Query_Sum(m+1,r,rt<<1|1,L,R))%mod;
    			else return Query_Sum(l,m,rt<<1,L,R);
    		else return Query_Sum(m+1,r,rt<<1|1,L,R);
    	}
    }t;
    
    int Fast_Pow(int x,int p)
    {
    	int tmp=1;
    	for(;p;p>>=1,x=1ll*x*x%mod)
    		if(p&1) tmp=1ll*tmp*x%mod;
    	return tmp;
    }
    bool Judge(int l,int r)
    {
    	Maxn=-mod, Minn=mod, t.Query(1,n,1,l,r);
    	if(Maxn-Minn!=r-l) return 0;
    	LL now=t.Query_Sum(1,n,1,l,r);
    	--Minn;
    	LL fact= 1ll*Maxn*(Maxn+1)%mod*(2*Maxn+1)%mod*inv6
    		    -1ll*Minn*(Minn+1)%mod*(2*Minn+1)%mod*inv6;
    	fact=(fact%mod+mod)%mod;
    //	printf("min:%d max:%d fact:%I64d now:%I64d
    ",Minn+1,Maxn,fact,now);
    	return now==fact;
    }
    
    int main()
    {
    	n=read(),q=read();
    	t.Build(1,n,1);
    	int opt,x,y;
    	inv6=Fast_Pow(6,mod-2);
    //	inv6=166666668;
    	while(q--)
    	{
    		opt=read(),x=read(),y=read();
    		if(opt==1) t.Modify(1,n,1,x,y);
    		else puts(Judge(x,y)?"damushen":"yuanxing");
    	}
    
    	return 0;
    }
    
  • 相关阅读:
    P3391 文艺平衡树
    隔离村庄(树形dp[01背包])
    cmd指令集
    vs的使用
    博客园第一天
    蓝桥杯 小生物的逃逸 模拟
    蓝桥杯 自行车停放 双向链表
    c++字符数组函数总结
    蓝桥杯 石子游戏 贪心
    蓝桥杯 最大获利 模拟
  • 原文地址:https://www.cnblogs.com/SovietPower/p/8444282.html
Copyright © 2011-2022 走看看