zoukankan      html  css  js  c++  java
  • 线段树维护区间开方/除法

    今天考试考了一些神仙数据结构

    T1 线段树维护区间加,区间开方,区间和

    (数据范围:5e5)

    T2 线段树维护区间加,区间除,区间和,区间最值

    对于这些题目,就像是之前考的区间与,区间或一样,除法,开方的操作会让各个数字之间越来越相近,最后变成一串一串连续的数字都是一样的,所以对于这一部分的操作我们一定程度上使用暴力,而如果一段都相等就相当于直接进行区间剪发的操作

    那么我们来看如何判断区间一段都相等,那我们只需要维护区间的最值,最小值==最大值就完全相等了

    然后.....代码.....被 (yurzhang) 神犇卡常,然后 (huyufeifei) 巨佬把我的 (T1) 改的面目全非......

    为了大常数的尊严 ,还是放被卡常的代码

    #include <bits/stdc++.h>
    
    using namespace std;
    
    #define ll long long
    #define re register
    #define gc getchar()
    inline ll read()
    {
    	re char c(gc);re ll x(0);
    	while(c<'0'||c>'9') c=gc;
    	while(c>='0'&&c<='9') x=x*10+c-48,c=gc;
    	return x;
    }
    
    const int N=5e5+10;
    
    ll a[N],s[N<<2],minn[N<<2],maxx[N<<2],add[N<<2];
    
    #define mid ((l+r)>>1)
    #define ls id<<1
    #define rs id<<1|1
    
    inline void pushup(int id)
    {
    	s[id]=s[ls]+s[rs];
        minn[id]=min(minn[ls],minn[rs]);
        maxx[id]=max(maxx[ls],maxx[rs]);
    } 
    inline void pushdown(int id,int l,int r)
    {
    	if(add[id]!=0)
    	{
    		re int lx=mid-l+1,rx=r-mid;
    		add[ls]+=add[id];
    		add[rs]+=add[id];
    		s[ls]+=add[id]*lx;
    		s[rs]+=add[id]*rx;
    		minn[rs]+=add[id];
    		minn[ls]+=add[id];
    		maxx[ls]+=add[id];
    		maxx[rs]+=add[id];
    		add[id]=0;
    	}
    }
    void built(int id,int l,int r)
    {
    	if(l==r)
    	{
    		s[id]=a[l];
    		minn[id]=a[l];
            maxx[id]=a[l];
    		return ;
    	} 
    	built (ls,l,mid);
    	built (rs,mid+1,r);
    	pushup(id);
    }
    void change(int id,int l,int r,int L,int R,ll x)
    {
    	if(l>=L&&r<=R)
    	{
    		s[id]+=x*(r-l+1);
    		add[id]+=x;
    		minn[id]+=x;
    		maxx[id]+=x;
    		return;
    	}
    	pushdown(id,l,r);
    	if(mid>=L) change(ls,l,mid,L,R,x);
    	if(mid<R) change(rs,mid+1,r,L,R,x);
    	pushup(id);
    }
    void Change(int id,int l,int r,int L,int R)
    {
    	if(l>=L&&r<=R&&floor(sqrt(maxx[id]))-maxx[id]==floor(sqrt(minn[id]))-minn[id])
    	{
    		ll d=floor(sqrt(maxx[id]))-maxx[id];
    //		cout<<maxx[id]<<' '<<d<<endl; 
            add[id]+=d;
    		maxx[id]+=d;
    		minn[id]+=d;
            s[id]+=d*(r-l+1);
            return;
    	}
        pushdown(id,l,r);
        if(L<=mid) Change(ls,l,mid,L,R);
        if(mid<R) Change(rs,mid+1,r,L,R);
        pushup(id);
    }
    ll query(int id,int l,int r,int L,int R)
    {
    	if(l>=L&&r<=R) return s[id];
    	pushdown(id,l,r);
    	ll ans=0;
    	if(L<=mid) ans+=query(ls,l,mid,L,R);
    	if(R>mid) ans+=query(rs,mid+1,r,L,R);
    	return ans;
    }
    
    int n,m;
    
    int main()
    {
    	freopen("comp.in","r",stdin);
    	freopen("comp.out","w",stdout);
    	n=read(),m=read();
    	for(int i=1;i<=n;++i) a[i]=read();
    	built(1,1,n);
    	while(m--)
    	{
    		int op=read(),l=read(),r=read();
    		if(op==1) {ll x=read();change(1,1,n,l,r,x);}
    		if(op==2) {cout<<query(1,1,n,l,r)<<endl;}
    		if(op==3) {Change(1,1,n,l,r);} 
    	}
    	return 0;
    }
    
    #include <bits/stdc++.h>
    
    using namespace std;
    
    #define re register
    #define gc getchar()
    inline int read()
    {
    	re char c(gc);re int x(0);
    	while(c<'0'||c>'9') c=gc;
    	while(c>='0'&&c<='9') x=x*10+c-48,c=gc;
    	return x;
    }
    
    #define ll long long
    const int N=1e5+10;
    
    ll a[N],s[N<<2],minn[N<<2],maxx[N<<2],add[N<<2];
    
    #define mid ((l+r)>>1)
    #define ls id<<1
    #define rs id<<1|1
    
    inline void pushup(int id)
    {
    	s[id]=s[ls]+s[rs];
        minn[id]=min(minn[ls],minn[rs]);
        maxx[id]=max(maxx[ls],maxx[rs]);
    } 
    inline void pushdown(int id,int l,int r)
    {
    	if(add[id]!=0)
    	{
    		re int lx=mid-l+1,rx=r-mid;
    		add[ls]+=add[id];
    		add[rs]+=add[id];
    		s[ls]+=add[id]*lx;
    		s[rs]+=add[id]*rx;
    		minn[rs]+=add[id];
    		minn[ls]+=add[id];
    		maxx[ls]+=add[id];
    		maxx[rs]+=add[id];
    		add[id]=0;
    	}
    }
    void built(int id,int l,int r)
    {
    	if(l==r)
    	{
    		s[id]=a[l];
    		minn[id]=a[l];
            maxx[id]=a[l];
    		return ;
    	} 
    	built (ls,l,mid);
    	built (rs,mid+1,r);
    	pushup(id);
    }
    void change(int id,int l,int r,int L,int R,ll x)
    {
    	if(l>=L&&r<=R)
    	{
    		s[id]+=x*(r-l+1);
    		add[id]+=x;
    		minn[id]+=x;
    		maxx[id]+=x;
    		return;
    	}
    	pushdown(id,l,r);
    	if(mid>=L) change(ls,l,mid,L,R,x);
    	if(mid<R) change(rs,mid+1,r,L,R,x);
    	pushup(id);
    }
    void Change(int id,int l,int r,int L,int R,ll x)
    {
    	if (l >=L&&r<=R&&maxx[id]-floor(maxx[id]/x)==minn[id]-floor(minn[id]/x))
    	{
    		ll d=floor(maxx[id]/x)-maxx[id];
            add[id]+=d;
    		maxx[id]+=d;
    		minn[id]+=d;
            s[id]+=d*(r-l+1);
            return;
    	}
        pushdown(id,l,r);
        if(L<=mid) Change(ls,l,mid,L,R,x);
        if(mid<R) Change(rs,mid+1,r,L,R,x);
        pushup(id);
    }
    ll query(int id,int l,int r,int L,int R)
    {
    	if(l>=L&&r<=R) return s[id];
    	pushdown(id,l,r);
    	ll ans=0;
    	if(L<=mid) ans+=query(ls,l,mid,L,R);
    	if(R>mid) ans+=query(rs,mid+1,r,L,R);
    	return ans;
    }
    ll Query(int id,int l,int r,int L,int R)
    {
    	if(l>=L&&r<=R) return maxx[id];
    	pushdown(id,l,r);
    	ll ans=0;
    	if(L<=mid) ans=max(ans,Query(ls,l,mid,L,R));
    	if(R>mid) ans=max(ans,Query(rs,mid+1,r,L,R));
    	return ans;
    }
    
    int n,m;
    
    int main()
    {
    	freopen("count.in","r",stdin);
    	freopen("count.out","w",stdout);
    	n=read(),m=read();
    	for(int i=1;i<=n;++i) a[i]=read();
    	built(1,1,n);
    	while(m--)
    	{
    		int op=read();
    		ll l=read(),r=read();
    		if(op==1) {int x=read();change(1,1,n,l,r,x);}
    		if(op==2) {cout<<query(1,1,n,l,r)<<endl;}
    		if(op==3) {cout<<Query(1,1,n,l,r)<<endl;}
    		if(op==4) {int x=read();Change(1,1,n,l,r,x);}
    	}
    	return 0;
    }
    
  • 相关阅读:
    121. Best Time to Buy and Sell Stock
    分页查询
    ViewPager
    SharedPreferences
    android 动画
    display~
    stringBuffer拼接有规律字符串
    修改placehosder
    this Activity.this Activity.class
    Windows基础编程SDK复习知识点
  • 原文地址:https://www.cnblogs.com/zijinjun/p/11047062.html
Copyright © 2011-2022 走看看