HDU-4027 Can you answer these queries? --线段树

Posted blame

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了HDU-4027 Can you answer these queries? --线段树相关的知识,希望对你有一定的参考价值。

题目链接:

http://acm.hdu.edu.cn/showproblem.php?pid=4027

题意及思路:

      有一排战舰,给出每个战舰的能力值,存在两种操作:第一种是把一定范围内所有战舰能力值开根号并向下取整,第二种是求一定区域内所有战舰能力值之和。如果我们暴力递归更新区间上的每一个点,会TLE(不要问我是怎么知道的)。我们可以稍微做一些优化。例如能力值0,1。它们开根号还是它们本身,不需要更新。我们可以增加一个标记tag。如果这个区间都是0或者1,我们就把tag标记为1。以后我们再次更新的时候如果区间tag为1,我们就不继续向下递归。

代码:

 1 #include <iostream>
 2 #include <cmath>
 3 #include <algorithm>
 4 #include <cstdio>
 5 #include <cstring>
 6 #define maxn 100000+5
 7 #define LL long long
 8 using namespace std;
 9 typedef struct node
10 
11     LL a;
12     int tag;
13 node;
14 node tree[maxn<<2];
15 void pushup(int rt)      //更新节点的和和tag值
16 
17     tree[rt].a=tree[rt<<1].a+tree[rt<<1|1].a;
18     if(tree[rt<<1].tag&&tree[rt<<1|1].tag)
19         tree[rt].tag=1;
20     return ;
21 
22 int build(int l,int r,int rt)
23 
24     if(l==r)
25     
26         scanf("%lld",&tree[rt].a);
27         if(tree[rt].a==0||tree[rt].a==1)
28             tree[rt].tag=1;
29         return  1;
30     
31     int m=(l+r)>>1;
32     build(l,m,rt<<1);
33     build(m+1,r,rt<<1|1);
34     pushup(rt);
35 
36 void update(int L,int R,int l,int r,int rt)
37 
38     if( L<=l  && r <= R&&tree[rt].tag==1)    //如果区间tag值为1,直接返回
39          return ;
40     if(l==r)
41     
42         tree[rt].a=(LL)(sqrt(1.0*tree[rt].a));
43         if(tree[rt].a==1||tree[rt].a==0)
44             tree[rt].tag=1;
45         return ;
46     
47     int m=(l+r)>>1;
48     if(L <= m)
49         update(L,R,l,m,rt<<1);
50     if(R >  m)
51         update(L,R,m+1,r,rt<<1|1);
52     pushup(rt);
53 
54 LL query(int L,int R,int l,int r,int rt)
55 
56     if(L <= l && r <= R)
57     
58         return tree[rt].a;
59     
60     int m=(l+r)>>1;
61     LL ans=0;
62     if(L <= m)
63         ans+=query(L,R,l,m,rt<<1);
64     if(R > m)
65         ans+=query(L,R,m+1,r,rt<<1|1);
66     return ans;
67 
68 int main()
69 
70     int n,jishu;
71     jishu=0;
72     while(scanf("%d",&n)!=EOF)
73     
74         printf("Case #%d:\n",++jishu);
75         build(1,n,1);
76         int k;
77         scanf("%d",&k);
78         while(k--)
79         
80             int c,a,b;
81             scanf("%d%d%d",&c,&a,&b);
82             if(a>b)
83                 swap(a,b);
84             if(c==0)
85                 update(a,b,1,n,1);
86             else
87                 cout<<query(a,b,1,n,1)<<endl;
88         
89         cout<<endl;
90     
91 

 

以上是关于HDU-4027 Can you answer these queries? --线段树的主要内容,如果未能解决你的问题,请参考以下文章

HDU 4027 Can you answer these queries? (线段树)

HDU-4027 Can you answer these queries?(线段树区间开方)

HDU 4027 Can you answer these queries?

Can you answer these queries? HDU - 4027

HDU 4027 Can you answer these queries?(线段树)

HDU4027 Can you answer these queries?