社区讨论

线段树直接暴力开平方不行嘛?

P4145上帝造题的七分钟 2 / 花神游历各国参与者 4已保存回复 5

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
5 条
当前快照
1 份
快照标识符
@lo1gqxfd
此快照首次捕获于
2023/10/22 20:46
2 年前
此快照最后确认于
2023/11/02 21:12
2 年前
查看原帖
1e12也开不了几次啊,感觉理论上没问题为啥t了,是不是实现错误
CPP
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int N=2e5+10;
int n,m,a[N];
struct Node{
	int l,r;ll w,mx;
}tr[N*4];
Node pushup(Node lc,Node rc){
	Node rt;rt.l=lc.l;rt.r=rc.r;
	rt.w=lc.w+rc.w;rt.mx=max(lc.mx,rc.mx);
	return rt;
}
void build(int u,int l,int r){
	if(l==r){
		tr[u]={l,r,a[l],a[l]};
		return;
	}
	int mid=l+r>>1;
	build(u<<1,l,mid);build(u<<1|1,mid+1,r);
	tr[u]=pushup(tr[u<<1],tr[u<<1|1]);
}
void modify(int u,int l,int r){
	if(tr[u].r<l||tr[u].l>r) return;
	if(!tr[u].mx) return;
	if(tr[u].l==tr[u].r){
		tr[u].w=sqrt(tr[u].w);
		tr[u].mx=tr[u].w;
		return;
	}
	modify(u<<1,l,r);modify(u<<1|1,l,r);
	tr[u]=pushup(tr[u<<1],tr[u<<1|1]);
}
ll query(int u,int l,int r){
	if(tr[u].l>=l&&tr[u].r<=r) return tr[u].w;
	int mid=tr[u].l+tr[u].r>>1;ll sum=0;
	if(l<=mid) sum=query(u<<1,l,r);
	if(r>mid) sum+=query(u<<1|1,l,r);
	return sum;
}
signed main(){
    scanf("%d",&n);
    for(int i=1;i<=n;i++) scanf("%d",&a[i]);
    build(1,1,n);
    scanf("%d",&m);
    while(m--){
    	int opt,l,r;scanf("%d%d%d",&opt,&l,&r);
		if(l>r) swap(l,r); 
		if(!opt) modify(1,l,r);
		if(opt) printf("%lld\n",query(1,l,r));
	}
    return 0;
}

回复

5 条回复,欢迎继续交流。

正在加载回复...