• 线段树 SP2713 GSS4


    SP2713 GSS4 - Can you answer these queries IV

    「题意」: n 个数,每个数在(10^{18}) 范围内。

    现在有「两种」操作

    0 x y把区间([x,y]) 内的每个数开方

    1 x y询问区间([x,y]) 的每个数的和

    「格式」: 有多组数据,数据以EOF结束,对于每组数据,输出数据的序号,每组数据之后输出一个空行。

    「注意」: 不保证给出的区间([x, y]) 有x<=y ,如果x>y 请交换x ,y 。

    之前做过花神那个题,但是是考试题,没有认真改。。。

    模了大佬@cellur925的题解才会。

    原来真的是暴力,但是一个(1*10^9)的数最多开方5次就会降低到1到2之间。这个时候就不用开方了。

    复杂度依旧是(mlogn),加了一个类似(log)的常数,差不多是5,6。

    code:

    #include<iostream>
    #include<cstdio>
    #include<cmath>
    #include<cstring>
    #define int long long
    #define ls(o) o<<1
    #define rs(o) o<<1|1
    using namespace std;
    const int wx=200017;
    inline int read(){
    	int sum=0,f=1;char ch=getchar();
    	while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    	while(ch>='0'&&ch<='9'){sum=(sum<<1)+(sum<<3)+ch-'0';ch=getchar();}
    	return sum*f;
    }
    struct val_tree{
    	int l,r,sum,ma;
    	#define sum(o) t[o].sum
    	#define ma(o) t[o].ma
    }t[wx*4];
    int a[wx];
    int n,m;
    void up(int o){
    	sum(o)=sum(ls(o))+sum(rs(o));
    	ma(o)=max(ma(ls(o)),ma(rs(o)));
    }
    void build(int o,int l,int r){
    	t[o].l=l;t[o].r=r;
    	if(l==r){sum(o)=ma(o)=a[l];return;}
    	int mid=t[o].l+t[o].r>>1;
    	if(l<=mid)build(ls(o),l,mid);
    	if(r>mid)build(rs(o),mid+1,r);
    	up(o);
    }
    void update(int o,int l,int r){
    	if(t[o].l==t[o].r){
    		sum(o)=(int)sqrt(sum(o));
    		ma(o)=(int)sqrt(ma(o));
    		return ;
    	}
    	int mid=t[o].l+t[o].r>>1;
    	if(l<=mid&&ma(ls(o))>1)update(ls(o),l,r);
    	if(r>mid&&ma(rs(o))>1)update(rs(o),l,r);
    	up(o);
    }
    int query(int o,int l,int r){
    	if(l<=t[o].l&&t[o].r<=r){
    		return sum(o);
    	}
    	int mid=t[o].l+t[o].r>>1;
    	int sum=0;
    	if(l<=mid)sum+=query(ls(o),l,r);
    	if(r>mid)sum+=query(rs(o),l,r);
    	return sum;
    }
    signed main(){
    	int cnt=0;
    	while(~scanf("%lld",&n)){
    		cnt++;
    		memset(a,0,sizeof a);
    		memset(t,0,sizeof t);
    		printf("Case #%lld:
    ",cnt);
    		for(int i=1;i<=n;i++)a[i]=read();
    		build(1,1,n);
    		m=read();
    		for(int i=1,opt,x,y;i<=m;i++){
    			opt=read();x=read();y=read();
    			if(x>y)swap(x,y);
    			if(opt)printf("%lld
    ",query(1,x,y));
    			else update(1,x,y);
    		}
    		puts("");
    	}
    }
    
  • 相关阅读:
    C# 设计模式(3)工厂方法模式
    C# 设计模式(2)简单工厂模式
    C# .Net Core读取AppSettings
    C# 设计模式(1)单例模式
    C# MarshalByRefObject
    使用64位TestStand调用32位LabVIEW代码模块
    LIN 总线入门
    C#版本与.NET版本对应关系以及各版本的特性
    数字货币提醒小工具
    C#根据描述获取枚举
  • 原文地址:https://www.cnblogs.com/wangxiaodai/p/9786759.html
Copyright © 2020-2023  润新知