HDU 4027 Can you answer these queries? 线段树,区间修改

            Can you answer these queries?


Problem Description

A lot of battleships of evil are arranged in a line before the battle. Our commander decides to use our secret weapon to eliminate the battleships. Each of the battleships can be marked a value of endurance. For every attack of our secret weapon, it could decrease the endurance of a consecutive part of battleships by make their endurance to the square root of it original value of endurance. During the series of attack of our secret weapon, the commander wants to evaluate the effect of the weapon, so he asks you for help.
You are asked to answer the queries that the sum of the endurance of a consecutive part of the battleship line.

Notice that the square root operation should be rounded down to integer.

Input

The input contains several test cases, terminated by EOF.
  For each test case, the first line contains a single integer N, denoting there are N battleships of evil in a line. (1 <= N <= 100000)
  The second line contains N integers Ei, indicating the endurance value of each battleship from the beginning of the line to the end. You can assume that the sum of all endurance value is less than 263.
  The next line contains an integer M, denoting the number of actions and queries. (1 <= M <= 100000)
  For the following M lines, each line contains three integers T, X and Y. The T=0 denoting the action of the secret weapon, which will decrease the endurance value of the battleships between the X-th and Y-th battleship, inclusive. The T=1 denoting the query of the commander which ask for the sum of the endurance value of the battleship between X-th and Y-th, inclusive.

Output

For each test case, print the case number at the first line. Then print one line for each query. And remember follow a blank line after each test case.

Sample Input

10

1 2 3 4 5 6 7 8 9 10

5

0 1 10

1 1 10

1 1 5

0 5 8

1 4 8

Sample Output

Case #1:

19 7 6

题意:给出一个n的数组,支持2种操作:

1.0 a b  :把a到b之间的数都开平方

2.1 a b  :查询区间a~b的数之和

注意:这道题求出的平方根要下取整。

   然后,每个样例之后有空行。

有个技巧,写在了注释。

  1 #include<cstdio>
  2 #include<cstring>
  3 #include<algorithm>
  4 #include<cmath>
  5
  6 using namespace std;
  7
  8 #define lson l,m,rt<<1
  9 #define rson m+1,r,rt<<1|1
 10 #define LL long long
 11 const int maxn=100000+5;
 12
 13 LL sum[maxn<<2];
 14
 15 //因为2^63总和最多2^63
 16 //如果只有1个数,也就最多开7次根号
 17 //即开着开着就恒为1
 18 //所以,当该区间的和等于区间长度(r-l)+1的时候,
 19 //该区间的值都不会再更新
 20
 21 //1表示这个区间不需要更新了
 22
 23 void pushup(int rt)
 24 {
 25     sum[rt]=sum[rt<<1]+sum[rt<<1|1];
 26
 27 }
 28
 29 void build(int l,int r,int rt)
 30 {
 31     if(l==r)
 32     {
 33         scanf("%lld",&sum[rt]);
 34         return ;
 35     }
 36
 37     int m=(l+r)>>1;
 38
 39     build(lson);
 40     build(rson);
 41     pushup(rt);
 42 }
 43
 44 void update(int L,int R,int l,int r,int rt)
 45 {
 46     if(sum[rt]==r-l+1)
 47         return ;
 48
 49     if(l==r)
 50     {
 51         sum[rt]=(LL)(sqrt((long double)sum[rt]));
 52         //printf("%lld ",sum[rt]);
 53         return ;
 54     }
 55
 56     int m=(l+r)>>1;
 57
 58     if(L<=m)
 59         update(L,R,lson);
 60     if(R>m)
 61         update(L,R,rson);
 62
 63     pushup(rt);
 64 }
 65
 66 LL query(int L,int R,int l,int r,int rt)
 67 {
 68     if(L<=l&&R>=r)
 69     {
 70         return sum[rt];
 71     }
 72
 73     int m=(l+r)>>1;
 74
 75     LL ret=0;
 76
 77     if(L<=m)
 78         ret+=query(L,R,lson);
 79     if(R>m)
 80         ret+=query(L,R,rson);
 81
 82     return ret;
 83 }
 84
 85 int main()
 86 {
 87     int cas=1;
 88
 89     int n;
 90
 91     while(scanf("%d",&n)!=EOF)
 92     {
 93         //memset(cal,0,sizeof(cal));
 94
 95         build(1,n,1);
 96
 97         int m;
 98         scanf("%d",&m);
 99
100         int T,x,y;
101
102         printf("Case #%d:\n",cas++);
103
104         for(int i=1;i<=m;i++)
105         {
106             scanf("%d %d %d",&T,&x,&y);
107
108             if(x>y)
109                 swap(x,y);
110
111             if(T==0)
112             {
113                 update(x,y,1,n,1);
114             }
115             else
116             {
117                 printf("%lld\n",query(x,y,1,n,1));
118             }
119         }
120
121         printf("\n");
122     }
123     return 0;
124 }

时间: 2024-10-09 19:42:21

HDU 4027 Can you answer these queries? 线段树,区间修改的相关文章

HDU 4027 Can you answer these queries? (线段树+区间点修改)

题意:给你 n 个数,m个询问(c,x,y) c==0 把x,y区间的值变为原来的平方根(向下取整) c==1 计算x,y区间的和. 利用1的开方永远为1剪枝.. #include<cstdio> #include<stdlib.h> #include<string.h> #include<string> //#include<map> #include<cmath> #include<iostream> #include

hdu 4027 Can you answer these queries? 线段树区间开根号,区间求和

Can you answer these queries? Time Limit: 1 Sec  Memory Limit: 256 MB 题目连接 http://acm.hdu.edu.cn/showproblem.php?pid=5195 Description A lot of battleships of evil are arranged in a line before the battle. Our commander decides to use our secret weapo

HDU 4027 Can you answer these queries?(线段树 区间不等更新)

题意  输入n个数  然后有两种操作   输入0时将给定区间所有数都变为自己的开方   输入1输出给定区间所有数的和 虽然是区间更新  但每个点更新的不一样  因此只能对单点进行更新  其实一个点最多被更新7次  2^64开平方7次后就变为1了  如果某个区间的数都变为了1  那么对这个区间的开方就不用考虑了   另外要注意给你的区间可能是反的 #include <bits/stdc++.h> #define lc p<<1,s,mid #define rc p<<1|

HDU - 4027 Can you answer these queries? (线段树区间更新+思维)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4027 题意:给定两种操作,查询(求出区间内的和),更新(区间内每个值都开根号,取整数) 题目给出所有数字之和小于263,所以最大的数最多7次也就变成1.所以在更新的时候加个判断条件,提前结束. 然后这道题目还有个坑,L有可能比R大,需要交换一下,(╬▔皿▔) . 1 #include <cstdio> 2 #include <algorithm> 3 #include <cmat

HDU 4027 Can you answer these queries?(线段树,区间更新,区间查询)

题目 线段树 简单题意: 区间(单点?)更新,区间求和 更新是区间内的数开根号并向下取整 这道题不用延迟操作 //注意: //1:查询时的区间端点可能前面的比后面的大: //2:优化:因为每次更新都是开平方,同一个数更新有限次数就一直是1了,所以可以这样优化 #include <stdio.h> #include<math.h> #define N 100010 #define LL __int64 #define lson l,m,rt<<1 #define rson

HDU 4027 Can you answer these queries? 线段树裸题

题意: 给定2个操作 0.把区间的每个数sqrt 2.求和 因为每个数的sqrt次数很少,所以直接更新到底,用个标记表示是否更新完全(即区间内的数字只有0,1就不用再更新了) #include<stdio.h> #include<iostream> #include<algorithm> #include<vector> #include<cmath> #include<queue> #include<set> #incl

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

Can you answer these queries? Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65768/65768 K (Java/Others)Total Submission(s): 9216    Accepted Submission(s): 2106 Problem Description A lot of battleships of evil are arranged in a line before

HDU-Can you answer these queries? (线段树+区间修改)

Problem Description A lot of battleships of evil are arranged in a line before the battle. Our commander decides to use our secret weapon to eliminate the battleships. Each of the battleships can be marked a value of endurance. For every attack of ou

HDU4027 Can you answer these queries 线段树区间求和+剪枝

给了你n,然后n个数字在一个数组中,接下来m个询问,每个询问三个数字 t,x,y,若t==0,那么修改区间[x,y]的每一个值,变为原来每个位置上的数 开根号取整,若t==1,那么对区间[x,y]求和 由于n,m,很大,所以树状数组铁定超时,若直接用线段树来做区间修改,那么也是超时,这类题目没别的方法了,静心剪枝,发现题目给的数据范围为2^63,有没有发现,2^63开根号 绝对不需要开10次,就能到1,到1以后就不需要再开了,意思就是若有某个区间[x,y]每一个点的值都为1时,这一段区间事实上是