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;
- }