题意:很多邪恶的战舰在战斗前排成一条线。我们的指挥官决定用我们的秘密武器消灭战舰。每艘战列舰都可以被标记为耐力的价值。对于我们的秘密武器的每一次攻击,都可以通过使其耐力达到其原始耐力值的平方根来降低战列舰连续部分的耐力。在我们秘密武器的一系列攻击中,指挥官想要评估武器的效果,所以他请求你的帮助。
你需要回答的问题是,连续部分的战舰线的耐力之和。
思路:因为是开方操作,所以不能乱搞区间操作,只能一个个点的更新。1的开方永远是1,所以当单点为1时特殊标记。如果在更新时遇到整段为1的区间,就可以跳过了。然后就是查数据。查数据应该不用解释了吧。。至于这题为什么不用for呢,自己脑补吧。
今天是618,买了个耳机本月就负债一百多了(感觉也太惨了吧)。然后要期末考试了,天天看高数有机化学都要吐了(大物还没开始自习,凉凉的感觉),今天实在看烦了就写道线段树冷静一下。然后输入的时候没有注意区间(输入u,v 可能u>v)然后疯狂RE (wc)。。。
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cstdio>
#include<cmath>
using namespace std;
const int maxn=100010;
struct node{
int left,right;
bool flag;
long long sum;
}tree[maxn*4];
long long ans,a;
void pushdowm(int root)
{
tree[root].sum=tree[root*2].sum+tree[root*2+1].sum;
tree[root].flag=tree[root*2].flag&&tree[root*2+1].flag;
}
void build(int root,int left,int right)
{
tree[root].left=left;
tree[root].right=right;
tree[root].flag=false;
if(left==right)
{
cin>>a;
tree[root].sum=a;
if(a<=1)tree[root].flag=true;
return;
}
int mid=(left+right)/2;
build(root*2,left,mid);
build(root*2+1,mid+1,right);
pushdowm(root);
}
void update(int root,int left,int right)
{
if(tree[root].flag)return;
if(tree[root].left==left&&tree[root].right==right&&left==right)
{
tree[root].sum=(long long)sqrt(tree[root].sum*1.0);
if(tree[root].sum<=1)tree[root].flag=true;
return;
}
int mid=(tree[root].left+tree[root].right)/2;
if(right<=mid)update(root*2,left,right);
else if(left>mid)update(root*2+1,left,right);
else {
update(root*2,left,mid);
update(root*2+1,mid+1,right);
}
pushdowm(root);
}
void que(int root,int left,int right)
{
if(tree[root].left==left&&tree[root].right==right)
{
ans+=tree[root].sum;
return;
}
int mid=(tree[root].left+tree[root].right)/2;
if(right<=mid)que(root*2,left,right);
else if(left>mid)que(root*2+1,left,right);
else{
que(root*2,left,mid);
que(root*2+1,mid+1,right);
}
}
int main()
{
cin.sync_with_stdio(false);
int n,m,u,v,q,cnt=0;
while(cin>>n)
{
build(1,1,n);//在建树时输入
cin>>m;
cout<<"Case #"<<++cnt<<":"<<endl;
while(m--)
{
cin>>q>>u>>v;
{
if(u>v)swap(u,v);//数据可能V>U 不交换会爆
if(q==0)update(1,u,v);
else
{
ans=0;
que(1,u,v);
cout<<ans<<endl;
}
}
}
cout<<endl;
}
return 0;
}