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

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:

  1. #include<iostream> 
  2. #include<algorithm> 
  3. #include<functional> 
  4. #include<cstring> 
  5. #include<cmath> 
  6. using namespace std; 
  7.  
  8. const int MAXN = 100010; 
  9.  
  10. typedef __int64 BigInt; 
  11.  
  12. typedef struct 
  13.     int left; 
  14.     int right; 
  15.      
  16.     BigInt sum; 
  17.     bool flag; 
  18. }SegNode; 
  19.  
  20. SegNode seg_tree[MAXN*3]; 
  21. BigInt value[MAXN]; 
  22.  
  23. void build(int id,int l,int r) 
  24.     seg_tree[id].left = l; 
  25.     seg_tree[id].right = r; 
  26.     seg_tree[id].flag = false
  27.      
  28.     if(l==r) 
  29.     { 
  30.         seg_tree[id].sum = value[l]; 
  31.          
  32.         if(value[l]==1) 
  33.         { 
  34.             seg_tree[id].flag = true
  35.         } 
  36.          
  37.         return
  38.     } 
  39.      
  40.     int mid = (l+r)/2; 
  41.      
  42.     build(2*id,l,mid); 
  43.     build(2*id+1,mid+1,r); 
  44.      
  45.     seg_tree[id].sum = seg_tree[2*id].sum +seg_tree[2*id+1].sum; 
  46.      
  47.     if(seg_tree[2*id].flag&&seg_tree[2*id+1].flag) 
  48.     { 
  49.         seg_tree[id].flag = true
  50.     } 
  51.  
  52. void update(int id,int l,int r) 
  53.     if(seg_tree[id].flag) 
  54.     { 
  55.         return
  56.     }else 
  57.     { 
  58.         if(seg_tree[id].left==seg_tree[id].right) 
  59.         { 
  60.             seg_tree[id].sum = static_cast<BigInt>(sqrt(1.0*seg_tree[id].sum)); 
  61.              
  62.             if(seg_tree[id].sum == 1) 
  63.             { 
  64.                 seg_tree[id].flag = true
  65.             } 
  66.              
  67.             return
  68.         }else 
  69.         { 
  70.             int mid = (seg_tree[id].left+seg_tree[id].right)/2; 
  71.              
  72.             if(r<=mid) 
  73.             { 
  74.                 update(2*id,l,r); 
  75.             }else if(l>mid) 
  76.             { 
  77.                 update(2*id+1,l,r); 
  78.             }else 
  79.             { 
  80.                 update(2*id,l,mid); 
  81.                 update(2*id+1,mid+1,r); 
  82.             } 
  83.              
  84.              
  85.         } 
  86.          
  87.     } 
  88.      
  89.     seg_tree[id].sum = seg_tree[2*id].sum +seg_tree[2*id+1].sum; 
  90.      
  91.     if(seg_tree[2*id].flag&&seg_tree[2*id+1].flag) 
  92.     { 
  93.         seg_tree[id].flag = true
  94.     } 
  95.  
  96. BigInt query(int id,int l,int r) 
  97.     if(seg_tree[id].left==l&&seg_tree[id].right==r) 
  98.     { 
  99.         return seg_tree[id].sum; 
  100.     }else 
  101.     { 
  102.         int mid = (seg_tree[id].left+seg_tree[id].right)/2; 
  103.          
  104.         if(r<=mid) 
  105.         { 
  106.             return query(2*id,l,r); 
  107.         }else if(l>mid) 
  108.         { 
  109.             return query(2*id+1,l,r); 
  110.         }else 
  111.         { 
  112.             return query(2*id,l,mid)+query(2*id+1,mid+1,r); 
  113.         } 
  114.     } 
  115.  
  116. int main() 
  117.     int nCase =0; 
  118.     int N,M; 
  119.     int a,b,c; 
  120.      
  121.     while(cin>>N) 
  122.     { 
  123.         for(int i=1;i<=N;i++) 
  124.         { 
  125.             scanf("%I64d",&value[i]); 
  126.         } 
  127.          
  128.         build(1,1,N); 
  129.         nCase++; 
  130.          
  131.         cin>>M; 
  132.          
  133.         cout<<"Case #"<<nCase<<":"<<endl; 
  134.          
  135.         while(M--) 
  136.         { 
  137.             scanf("%d%d%d",&a,&b,&c); 
  138.              
  139.             if(b>c) 
  140.             { 
  141.                 swap(b,c); 
  142.             } 
  143.              
  144.             if(a==0) 
  145.             { 
  146.                 update(1,b,c); 
  147.             }else 
  148.             { 
  149.                 printf("%I64d\n",query(1,b,c)); 
  150.             } 
  151.         } 
  152.          
  153.         cout<<endl; 
  154.     } 
  155.     return 0; 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值