Can you answer these queries?(线段树)

题目传送门

Can you answer these queries?

题目大意

给你一个长度为n的序列,和序列中每个元素的值,和m次操作
分别给出op,x,y
如果op=0则更新区间x~y,更新操作为对每个值取平方根向下取整
op==1则查询区间x~y的元素和

思路

显然线段树(毕竟我是练习线段树才找的这个题),区间更新,区间查询,维护区间和
注意点比较多:
元素的范围是long long
每组数据后换行
区间均为1时特判一下,不进行后续更新
区间x不一定小于y,记得处理一下

AC Code

#include<bits/stdc++.h>
using namespace std;
#define debug(a) cout<<#a<<"="<<a<<endl;
const int N=1e5 +9;
int n, m;
long long a[N];
int op, x, y;
struct segtree{
	long long sum;
}tr[N<<2];
inline int lc(int p) {return p<<1;}
inline int rc(int p) {return p<<1|1;}
inline void push_up(int p) {tr[p].sum=tr[lc(p)].sum + tr[rc(p)].sum;}
inline void build(int p, int l, int r){
	if(l==r)	{scanf("%lld", &tr[p].sum); return ;}
	int mid=(l+r)>>1;
	build(lc(p), l, mid);
	build(rc(p), mid+1, r);
    push_up(p);
}
inline void updata(int p, int l, int r, int x, int y){
	if(x==y){
        tr[p].sum=sqrt(tr[p].sum);
		return ;
	}
    if(l<=x && r>=y && tr[p].sum==y-x+1) return ;
	int mid=(x+y)>>1;
	if(l<=mid) updata(lc(p), l, r, x, mid);
	if(r>mid) updata(rc(p), l, r, mid+1, y);
    push_up(p);
}
inline long long query(int p, int l, int r, int x, int y){
    if(l<=x && r>=y) return tr[p].sum;
    long long ans=0;
    int mid=(x+y)>>1;
    if(l<=mid)  ans+=query(lc(p), l, r, x, mid);
    if(r>mid)   ans+=query(rc(p), l, r, mid+1, y);
    return ans;
}
signed main(){
    int k=0;
    while(scanf("%d", &n)!=EOF){
        build(1,1,n);
        scanf("%d", &m);
        printf("Case #%d:\n", ++k);
        while(m--){
            scanf("%d%d%d", &op, &x, &y);
            if(x>y) swap(x,y);
            if(op) printf("%lld\n", query(1,x,y,1,n));
            else   updata(1,x,y,1,n);
        }
        printf("\n");
    }
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值