HDU--4027(Can you answer these queries?)

来源:互联网 发布:linux vi 翻页到最后 编辑:程序博客网 时间:2024/05/16 13:46

The Meanings Of Problems:

 首先给你一些数组的初始值,然后给你一定数目的操作,操作的类型一共有两种,‘0’ a b 操作,将a-b区间内的数字都变为其平方根,‘1’ a b 操作,求出a-b区间的所有数字和。

Subject Categories:

 Segment_tree

Algorithm Descriptions:

 首先可以肯定是一个线段树的题目。

必要的三个操作:

  1. 线段树的创建  segmentTree_Construct
  2. 线段树的更新  segmentTree_Update
  3. 线段树的查询  segmentTree_Query
分析一下,显然题目查询很多,要二分查找线段树(Binary_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;}


原创粉丝点击