The Meanings Of Problems:
首先给你一些数组的初始值,然后给你一定数目的操作,操作的类型一共有两种,‘0’ a b 操作,将a-b区间内的数字都变为其平方根,‘1’ a b 操作,求出a-b区间的所有数字和。
Subject Categories:
Segment_tree
Algorithm Descriptions:
首先可以肯定是一个线段树的题目。
必要的三个操作:
- 线段树的创建 segmentTree_Construct
- 线段树的更新 segmentTree_Update
- 线段树的查询 segmentTree_Query
接着,分析可以知道,一旦一个区间a-b的和等于a-b区间数字个数,则没有必要对
线段树的左右字数进行操作。
Input:{数组的初始值}、操作
Output:每一个o操作对应的和
Main:
read(array_init);
segmentTree_Construct();
for_each 每一条操作
if is '0' 操作
segmentTree_Update();
else
segmentTree_Query();
endif
end
Codes:
#include<iostream>
#include<algorithm>
#include<functional>
#include<cstring>
#include<cmath>
using namespace std;
const int MAXN = 100010;
typedef __int64 BigInt;
typedef struct
{
int left;
int right;
BigInt sum;
bool flag;
}SegNode;
SegNode seg_tree[MAXN*3];
BigInt value[MAXN];
void build(int id,int l,int r)
{
seg_tree[id].left = l;
seg_tree[id].right = r;
seg_tree[id].flag = false;
if(l==r)
{
seg_tree[id].sum = value[l];
if(value[l]==1)
{
seg_tree[id].flag = true;
}
return ;
}
int mid = (l+r)/2;
build(2*id,l,mid);
build(2*id+1,mid+1,r);
seg_tree[id].sum = seg_tree[2*id].sum +seg_tree[2*id+1].sum;
if(seg_tree[2*id].flag&&seg_tree[2*id+1].flag)
{
seg_tree[id].flag = true;
}
}
void update(int id,int l,int r)
{
if(seg_tree[id].flag)
{
return ;
}else
{
if(seg_tree[id].left==seg_tree[id].right)
{
seg_tree[id].sum = static_cast<BigInt>(sqrt(1.0*seg_tree[id].sum));
if(seg_tree[id].sum == 1)
{
seg_tree[id].flag = true;
}
return ;
}else
{
int mid = (seg_tree[id].left+seg_tree[id].right)/2;
if(r<=mid)
{
update(2*id,l,r);
}else if(l>mid)
{
update(2*id+1,l,r);
}else
{
update(2*id,l,mid);
update(2*id+1,mid+1,r);
}
}
}
seg_tree[id].sum = seg_tree[2*id].sum +seg_tree[2*id+1].sum;
if(seg_tree[2*id].flag&&seg_tree[2*id+1].flag)
{
seg_tree[id].flag = true;
}
}
BigInt query(int id,int l,int r)
{
if(seg_tree[id].left==l&&seg_tree[id].right==r)
{
return seg_tree[id].sum;
}else
{
int mid = (seg_tree[id].left+seg_tree[id].right)/2;
if(r<=mid)
{
return query(2*id,l,r);
}else if(l>mid)
{
return query(2*id+1,l,r);
}else
{
return query(2*id,l,mid)+query(2*id+1,mid+1,r);
}
}
}
int main()
{
int nCase =0;
int N,M;
int a,b,c;
while(cin>>N)
{
for(int i=1;i<=N;i++)
{
scanf("%I64d",&value[i]);
}
build(1,1,N);
nCase++;
cin>>M;
cout<<"Case #"<<nCase<<":"<<endl;
while(M--)
{
scanf("%d%d%d",&a,&b,&c);
if(b>c)
{
swap(b,c);
}
if(a==0)
{
update(1,b,c);
}else
{
printf("%I64d\n",query(1,b,c));
}
}
cout<<endl;
}
return 0;
}