每天一个线段树,慢腾腾的学,啧
正常写的话超时,又因为不是模板类型题,所以我们得想一个剪枝的方法,事实上经过
几次开根号之后,都会变成1,之后就不需要重复操作了,标记一下就好
有两个注意的点:1.给的数据x和y大小不确定,需要自己判断一下
2.long long int的问题(因为方便就都设为ll了)
格式的话记得最后空格
代码如下,已AC
#include <iostream>
#include <algorithm>
#include <vector>
#include <map>
#include <cstring>
#include <queue>
#include <stack>
#include<cstdio>
#include<cmath>
using namespace std;
long long int sum[1000000],a[1000000],lazy[1000000];
void build(long long int l,long long int r,long long int p){
if(l==r){
sum[p]=a[l];
return ;
}
long long int mid=(l+r)/2;
build(l,mid,p<<1);
build(mid+1,r,(p<<1)+1);
sum[p]=sum[p<<1]+sum[(p<<1)+1];
}
void denote(long long int x,long long int y,long long int l,long long int r,long long int p){
if(l==r){
if(l>=x&&l<=y){
sum[p]=(long long int)sqrt(sum[p]);
}
return ;
}
long long int mid=(l+r)/2;
if(x<=mid&&(mid-l+1)!=sum[p<<1])//剪枝特判
denote(x,y,l,mid,p<<1);
if(y>mid&&(r-mid)!=sum[(p<<1)+1])
denote(x,y,mid+1,r,(p<<1)+1);
sum[p]=sum[p<<1]+sum[(p<<1)+1];
}
long long int ans=0;
void query(long long int x,long long int y,long long int l,long long int r,long long int p){
if(l>=x&&r<=y){
ans+=sum[p];
return ;
}
long long int mid=(l+r)/2;
if(x<=mid)
query(x,y,l,mid,p<<1);
if(y>mid)
query(x,y,mid+1,r,(p<<1)+1);
}
int main(){
long long int n,m,c,l,r,num=0;
while(scanf("%lld",&n)!=EOF){
num++;
printf("Case #%lld:\n",num);
for(int i=1;i<=n;i++){
scanf("%lld",&a[i]);
}
build(1,n,1);
scanf("%lld",&m);
for(int i=0;i<m;i++){
scanf("%lld%lld%lld",&c,&l,&r);
long long int w;
if(l>r){//坑点,x,y大小不确定
w=l;l=r;r=w;
}
if(c==0)
denote(l,r,1,n,1);
if(c==1){
query(l,r,1,n,1);
printf("%lld\n",ans);
ans=0;
}
}
printf("\n");
}
return 0;
}