zoukankan      html  css  js  c++  java
  • 【CF438D】The Child and Sequence(线段树)

    点此看题面

    大致题意: 给你一个序列,让你支持区间求和、区间取模、单点修改操作。

    区间取模

    区间求和和单点修改显然都很好维护吧,难的主要是区间取模。

    取模标记无法叠加,因此似乎只能暴力搞?

    实际上,我么先考虑一个结论:

    一个数(x)向一个不大于它的数(p)取模,所得结果必然小于(frac x2)

    证明:

    (plefrac x2)时,由于(x\%p<p),所以(x\%p<frac x2)

    (p>frac x2)时,由于(ple x),所以(x\%p=x-p<x-frac x2<frac x2)

    所以,这个数减小的速度是非常快的。

    同时我们又有一个显然的性质:

    一个数(x)向一个大于它的数(p)取模,所得结果必然为(x)本身。

    因此,我们可以考虑在原本暴力基础上加一个剪枝:

    若取模区间内最大值小于当前模数,就可以直接(return)掉。

    这样一来,就做完了?

    代码

    #include<bits/stdc++.h>
    #define Tp template<typename Ty>
    #define Ts template<typename Ty,typename... Ar>
    #define Reg register
    #define RI Reg int
    #define Con const
    #define CI Con int&
    #define I inline
    #define W while
    #define N 100000
    #define LL long long
    using namespace std;
    int n,a[N+5];
    class FastIO
    {
    	private:
    		#define FS 100000
    		#define tc() (A==B&&(B=(A=FI)+fread(FI,1,FS,stdin),A==B)?EOF:*A++)
    		#define pc(c) (C==E&&(clear(),0),*C++=c)
    		#define tn (x<<3)+(x<<1)
    		#define D isdigit(c=tc())
    		int T;char c,*A,*B,*C,*E,FI[FS],FO[FS],S[FS];
    	public:
    		I FastIO() {A=B=FI,C=FO,E=FO+FS;}
    		Tp I void read(Ty& x) {x=0;W(!D);W(x=tn+(c&15),D);}
    		Ts I void read(Ty& x,Ar&... y) {read(x),read(y...);}
    		Tp I void write(Ty x) {W(S[++T]=x%10+48,x/=10);W(T) pc(S[T--]);}
    		Tp I void writeln(Con Ty& x) {write(x),pc('
    ');}
    		I void clear() {fwrite(FO,1,C-FO,stdout),C=FO;}
    }F;
    class SegmentTree//线段树
    {
    	private:
    		#define P CI l=1,CI r=n,CI rt=1
    		#define L l,mid,rt<<1
    		#define R mid+1,r,rt<<1|1
    		#define PU(x) (Mx[x]=max(Mx[x<<1],Mx[x<<1|1]),S[x]=S[x<<1]+S[x<<1|1])
    		LL Mx[N<<2],S[N<<2];
    	public:
    		I void Build(P)//建树
    		{
    			if(l==r) return (void)(Mx[rt]=S[rt]=a[l]);RI mid=l+r>>1;
    			Build(L),Build(R),PU(rt);
    		}
    		I void Mod(CI tl,CI tr,CI X,P)//区间取模
    		{
    			if(Mx[rt]<X) return;if(l==r) return (void)(Mx[rt]%=X,S[rt]%=X);RI mid=l+r>>1;
    			tl<=mid&&(Mod(tl,tr,X,L),0),tr>mid&&(Mod(tl,tr,X,R),0),PU(rt);
    		}
    		I void Upt(CI x,CI y,P)//单点修改
    		{
    			if(l==r) return (void)(Mx[rt]=S[rt]=y);RI mid=l+r>>1;
    			x<=mid?Upt(x,y,L):Upt(x,y,R),PU(rt);
    		}
    		I LL Query(CI tl,CI tr,P)//区间求和
    		{
    			if(tl<=l&&r<=tr) return S[rt];RI mid=l+r>>1;
    			return (tl<=mid?Query(tl,tr,L):0)+(tr>mid?Query(tl,tr,R):0);
    		}
    }S;
    int main()
    {
    	RI Qt,i,op,x,y,z;for(F.read(n,Qt),i=1;i<=n;++i) F.read(a[i]);
    	S.Build();W(Qt--) switch(F.read(op,x,y),op)
    	{
    		case 1:F.writeln(S.Query(x,y));break;
    		case 2:F.read(z),S.Mod(x,y,z);break;
    		case 3:S.Upt(x,y);break;
    	}return F.clear(),0;
    }
    
  • 相关阅读:
    Java基础(01)--简介及基础语法
    高数(01)--函数、极限、连续
    未来行业及趋势
    HttpRunner基础使用一:
    web自动化中js操作的操作应用
    django框架学习六:优化views.py文件,使用rest_framework中的APIVew和Response返回
    django框架学习五:djangorestframework中ModelSerializer的关联字段的生成
    django框架学习四:引入djangorestframework中ModelSerializer
    django框架学习三:djangorestframework中序列化器的优化:添加单字段、多字段、自定义函数的校验
    django框架学习三:使用DRF框架,引入序列化器,实现对数据库的增删改查操作
  • 原文地址:https://www.cnblogs.com/chenxiaoran666/p/CF438D.html
Copyright © 2011-2022 走看看