TLE 求助:望好心人指点
查看原帖
TLE 求助:望好心人指点
357520
SinoNav楼主2020/9/13 17:25

题目大意:区间开方求和(线段树)

思路:常规(一个节点如果全都是1了就book它以下,以后不管)

问题:提交并修改,若干次,每次都在第一个测试点显示tle

向大家表示真诚的感激

#include <bits/stdc++.h>
using namespace std;
#define int long long
const int N=1e6+5;
int a[N],t[N],book[N],_case=0;
void read(int &p){
    int x=0; char ch=getchar();
    while(ch<'0'||ch>'9') ch=getchar();
    while(ch>='0'&&ch<='9') x=(x<<1)+(x<<3)+(ch^48),ch=getchar();
    p=x;
}
void pushup(int k){
	t[k]=t[k<<1]+t[k<<1|1];
	book[k]=book[k<<1]&&book[k<<1|1];
}
void build(int l,int r,int k){
	if(l==r){
		t[k]=a[l];
		book[k]=(a[l]==1);
	}
	else {
		int mid=(l+r)/2;
		build(l,mid,k<<1);
		build(mid+1,r,k<<1|1);
		pushup(k);
	}
}
void updata(int L,int R,int l,int r,int k){
	if(l==r){
		t[k]=sqrt(t[k]);
		book[k]=(t[k]==1);
	}
	else {
		int mid=(l+r)/2;
		if(L<=mid && !book[k<<1]) updata(L,R,l,mid,k<<1);
		if(R>mid && !book[k<<1|1]) updata(L,R,mid+1,r,k<<1|1);
		pushup(k);
	}
}
int query(int L,int R,int l,int r,int k){
	if(L<=l && r<=R) return t[k];
	else {
		int mid=(l+r)/2,res=0;
		if(L<=mid) res+=query(L,R,l,mid,k<<1);
		if(R>mid) res+=query(L,R,mid+1,r,k<<1|1);
		return res;
	}
}
void work(int n){
	printf("Case #%d:\n",++_case);
	int m,opt,l,r;
	for(int i=1;i<=n;i++) read(a[i]);
	build(1,n,1);
	read(m);
	while(m--){
		read(opt),read(l),read(r);
		if(opt==0) updata(l,r,1,n,1);
		else printf("%d\n",query(l,r,1,n,1));
	}
}
signed main()
{
	int n;
	while(~scanf("%d",&n)){
		work(n);
		puts("");
	}
	return 0;
}
2020/9/13 17:25
加载中...