Can you answer these queries?

Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65768/65768 K (Java/Others)
Total Submission(s): 10249    Accepted Submission(s): 2350

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

  1. 10
  2. 1 2 3 4 5 6 7 8 9 10
  3. 5
  4. 0 1 10
  5. 1 1 10
  6. 1 1 5
  7. 0 5 8
  8. 1 4 8
 

Sample Output

  1. Case #1:
  2. 19
  3. 7
  4. 6
Source

之前听说过很多神级线段树的题,最后都是暴力拼循环节,今天难得见一个入门级别的,也算涨姿势了~

题意:给定n个数(1~100000),两种操作(1~100000)0 or 1 ,0操作是把给定区间内的数都变成原来的开方(向下取整),1操作,询问区间内的数的总和;

突破点:所有数据和的范围是2的63此方,大神们发现开方六七次以后,这些数就都变成1了~所以就不需要再向下更新了,

那么判定不需要更新的条件就是:该节点下的区间总和与该区间长度相等,那么它们妥妥都是1了,就可以返回。

但是本题坑坑比较多~

1坑:给定区间 Xth 与 Yth大小关系不定,记得用下swap~,不然就是RE(非法访问)。

2坑 : 每组测试实例最后还需要多输出一个空行~

0.0也怪不细心~

  1. #include <stdio.h>
  2. #include <string.h>
  3. #include <stdlib.h>
  4. #include <math.h>
  5. #include <iostream>
  6. #include <algorithm>
  7. #include <climits>
  8. #include <queue>
  9. #define ll long long
  10.  
  11. using namespace std;
  12.  
  13. const int MAX = ;
  14. ll num[MAX];
  15.  
  16. struct nodes
  17. {
  18. int left,right;
  19. ll large;
  20. } tree[MAX*];
  21.  
  22. void pushup(int root)
  23. {
  24. tree[root].large = tree[root*].large + tree[root*+].large;
  25. }
  26. void build(int root,int left,int right)
  27. {
  28. tree[root].left = left;
  29. tree[root].right = right;
  30. if(left == right)
  31. {
  32. tree[root].large = num[left];
  33. return;
  34. }
  35.  
  36. int mid = (left+right)/;
  37.  
  38. build(*root,left,mid);
  39. build(*root+,mid+,right);
  40.  
  41. pushup(root);
  42. }
  43.  
  44. void update(int root,int left,int right)
  45. {
  46. if(tree[root].large == tree[root].right - tree[root].left + )
  47. return;
  48. if(tree[root].right == tree[root].left)
  49. {
  50. tree[root].large = (ll)sqrt(tree[root].large);
  51. return;
  52. }
  53. int mid = (tree[root].left+tree[root].right)/;
  54. if(left <= mid && right > mid)
  55. {
  56. update(*root,left,mid);
  57. update(*root+,mid+,right);
  58. }
  59. else if(left > mid)
  60. {
  61. update(*root+,left,right);
  62. }
  63. else
  64. {
  65. update(*root,left,right);
  66. }
  67. pushup(root);
  68. }
  69.  
  70. ll query(int root ,int left,int right)
  71. {
  72. if(tree[root].large == tree[root].right - tree[root].left + )
  73. {
  74. return right - left + ;
  75. }
  76. if(left == tree[root].left && right == tree[root].right)
  77. {
  78. return tree[root].large;
  79. }
  80. int mid = (tree[root].left+tree[root].right)/;
  81. ll ans = ;
  82. if(right > mid && left <= mid)
  83. {
  84. ans += query(*root,left,mid);
  85. ans += query(*root+,mid+,right);
  86. }
  87. else if(left > mid)
  88. {
  89. ans += query(*root+,left,right);
  90. }
  91. else
  92. {
  93. ans += query(*root,left,right);
  94. }
  95. return ans;
  96. }
  97.  
  98. int main(void)
  99. {
  100. int i,cmd,x,y,n,q,cnt= ;
  101. while(scanf("%d",&n) != -)
  102. {
  103. for(i = ; i <= n; i++)
  104. scanf("%lld",&num[i]);
  105. build(,,n);
  106. scanf("%d",&q);
  107. printf("Case #%d:\n",cnt++);
  108. for(i = ; i <q; i++)
  109. {
  110. scanf("%d %d %d",&cmd,&x,&y);
  111. if(y < x)
  112. swap(x,y);
  113. if(cmd)
  114. printf("%lld\n",query(,x,y));
  115. else
  116. update(,x,y);
  117. }
  118. printf("\n");
  119. }
  120. return ;
  121. }

精简版

  1. #include <stdio.h>
  2. #include <string.h>
  3. #include <stdlib.h>
  4. #include <math.h>
  5. #include <iostream>
  6. #include <algorithm>
  7. #include <climits>
  8. #include <queue>
  9. #define ll long long
  10.  
  11. using namespace std;
  12.  
  13. struct Segment_T
  14. {
  15. static const int MAX = 1e5+;
  16. ll num[MAX];
  17. struct nodes
  18. {
  19. int lt,rt;
  20. ll add,sum;
  21. } T[MAX*];
  22.  
  23. Segment_T(){}
  24.  
  25. void pushup(int R)
  26. {
  27. T[R].sum = T[R<<].sum + T[R<<|].sum;
  28. }
  29. void pushdown(int R)
  30. {
  31. if(T[R].add)
  32. {
  33. T[R<<].add += T[R].add;
  34. T[R<<|].add += T[R].add;
  35. T[R<<].sum += T[R].add * (T[R<<].rt - T[R<<].lt + );
  36. T[R<<|].sum += T[R].add * (T[R<<|].rt - T[R<<|].lt + );
  37. T[R].add = ;
  38. }
  39. }
  40. void build(int R,int lt,int rt)
  41. {
  42. T[R].lt = lt;
  43. T[R].rt = rt;
  44. if(lt == rt)
  45. {
  46. T[R].sum = num[lt];
  47. return;
  48. }
  49. int mid = (lt+rt)>>;
  50.  
  51. build(R<<,lt,mid);
  52. build(R<<|,mid+,rt);
  53.  
  54. pushup(R);
  55. }
  56. void update(int R,int lt,int rt)
  57. {
  58. if(T[R].sum == T[R].rt - T[R].lt + )
  59. return;
  60. if(T[R].rt == T[R].lt)
  61. {
  62. T[R].sum = (ll)sqrt(T[R].sum); //返回操作处
  63. return;
  64. }
  65. int mid = (T[R].lt+T[R].rt)>>;
  66. if(lt <= mid && rt > mid)
  67. {
  68. update(R<<,lt,mid);
  69. update(R<<|,mid+,rt);
  70. }
  71. else if(lt > mid)
  72. update(R<<|,lt,rt);
  73. else
  74. update(R<<,lt,rt);
  75. pushup(R);
  76. }
  77. ll query(int R,int lt,int rt)
  78. {
  79. if(T[R].sum == T[R].rt - T[R].lt + )
  80. {
  81. return rt - lt + ;
  82. }
  83. if(lt == T[R].lt && rt == T[R].rt)
  84. {
  85. return T[R].sum; //返回操作处
  86. }
  87. int mid = (T[R].lt+T[R].rt)>>;
  88. ll ans = ;
  89. if(rt > mid && lt <= mid)
  90. ans = query(R<<,lt,mid) + query(R<<|,mid+,rt);
  91. else if(lt > mid)
  92. ans += query(R<<|,lt,rt);
  93. else
  94. ans += query(R<<,lt,rt);
  95. return ans;
  96. }
  97. };
  98. Segment_T Tr;
  99. int main(void)
  100. {
  101. int i,cmd,x,y,n,q,cnt= ;
  102. while(scanf("%d",&n) != -)
  103. {
  104. for(i = ; i <= n; i++)
  105. scanf("%lld",&Tr.num[i]);
  106. Tr.build(,,n);
  107. scanf("%d",&q);
  108. printf("Case #%d:\n",cnt++);
  109. for(i = ; i <q; i++)
  110. {
  111. scanf("%d %d %d",&cmd,&x,&y);
  112. if(y < x)
  113. swap(x,y);
  114. if(cmd)
  115. printf("%lld\n",Tr.query(,x,y));
  116. else
  117. Tr.update(,x,y);
  118. }
  119. printf("\n");
  120. }
  121. return ;
  122. }

hdu 4027 Can you answer these queries? (区间线段树,区间数开方与求和,经典题目)的更多相关文章

  1. HDU 4027—— Can you answer these queries?——————【线段树区间开方,区间求和】

    Can you answer these queries? Time Limit:2000MS     Memory Limit:65768KB     64bit IO Format:%I64d & ...

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

    Can you answer these queries? Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65768/65768 K ...

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

    https://cn.vjudge.net/problem/HDU-4027 题意 给一个有初始值的数组,存在两种操作,T=0时将[L,R]的值求平方根,T=1时查询[L,R]的和. 分析 显然不符合 ...

  4. HDU 4027 Can you answer these queries?(线段树的单点更新+区间查询)

    题目链接 题意 : 给你N个数,进行M次操作,0操作是将区间内的每一个数变成自己的平方根(整数),1操作是求区间和. 思路 :单点更新,区间查询,就是要注意在更新的时候要优化,要不然会超时,因为所有的 ...

  5. HDU 4027 Can you answer these queries【线段树】

    <题目链接> 题目大意: 给定一段序列,现在对指定区间进行两种操作:一是对指定区间进行修改,对其中的每个数字都开根号(开根号后的数字仍然取整):二是对指定区间进行查询,查询这段区间所有数字 ...

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

    给定一个长度为n的序列,m次操作. 每次操作 可以将一个区间内的所有数字变为它的根号. 可以查询一个区间内所有元素的和. 线段树的初级应用. 如果把一个区间内的元素都改为它的根号的话,是需要每个数字都 ...

  7. hdu 4027 Can you answer these queries?[线段树]

    题目 题意: 输入一个 :n  .(1<=n<<100000) 输入n个数    (num<2^63) 输入一个m :代表m个操作    (1<=m<<100 ...

  8. HDU 4027 Can you answer these queries(线段树 + 观察 )

    这题主要考察观察能力. 2^63最多只需要开7次根号就会变成1,当数字变成1之后就不需要再对其进行操作. 对于含有大于1数字的区间,向下更新. 对于数字全为1的区间,直接返回. #include &l ...

  9. SPOJ GSS1_Can you answer these queries I(线段树区间合并)

    SPOJ GSS1_Can you answer these queries I(线段树区间合并) 标签(空格分隔): 线段树区间合并 题目链接 GSS1 - Can you answer these ...

  10. HDU 4027 Can you answer these queries? (线段树区间修改查询)

    描述 A lot of battleships of evil are arranged in a line before the battle. Our commander decides to u ...

随机推荐

  1. PAT甲级——A1099 Build A Binary Search Tree

    A Binary Search Tree (BST) is recursively defined as a binary tree which has the following propertie ...

  2. Java 常用正则表达式

    一. 只能输入数字:"^[0-9]*$".只能输入n位的数字:"^\d{n}$".只能输入至少n位的数字:"^\d{n,}$".只能输入m~ ...

  3. java日志管理 - slf4j+log4j2

    1 . 概述 1.1  日志框架实现 log4j是apache实现的一个开源日志组件: logback同样是由log4j的作者设计完成的,拥有更好的特性,用来取代log4j的一个日志框架,是slf4j ...

  4. flock文件锁的学习和应用

    flock文件锁 学习与应用  2016-9-20 作用: 可以使用flock文件锁,避免指定命令的同时执行.(实现任务锁定,解决冲突) 用法: # flock -xn /opt/lock_file ...

  5. Java室内最短路径搜索(支持多楼层)

    修改了上次的代码,现在支持室内的多楼层情况下的最短路径搜索,还是使用A*算法,把在GraphAdjList中VNode没有利用起来的data字段作为我们存储楼层属性的位置. 实际上是我偷懒了,正常情况 ...

  6. Pandas对于CSV的简单操作

    Pandas对于CSV的简单操作 最近在研究pandas对于csv文件的读取以及一些操作,网上的信息比较乱,写篇博客记录一下,毕竟自己写的才是最适合自己的用法. 首先我们应该都知道,pandas是一个 ...

  7. <每日一题>题目22:简单的python练习题(31-40)

    #31.分布式爬虫主要解决什么问题? ''' ip 带宽 CPU IO ''' #32.网络传输层 ''' 应用层—http ftp dns nfs 传输层—tcp --udp 网络层—ip icmp ...

  8. 跟我一起了解koa之koa-generator(一)

    cnpm install -g koa-generator koa2 -e koa2-learn cd koa2-learn/ cnpm install 使用如下运行 DEBUG=koa2-learn ...

  9. CSP-S模拟41影子,玫瑰花精题解

    题面:https://www.cnblogs.com/Juve/articles/11523567.html 影子: 暴力方法:枚举每一对点暴力统计最小权 优化:考虑并查集,枚举每个点,如果没有被访问 ...

  10. [JSOI2010]连通数 (dfs或tarjan或bitset)+bitset学习

    题目描述 输入格式 输入数据第一行是图顶点的数量,一个正整数N. 接下来N行,每行N个字符.第i行第j列的1表示顶点i到j有边,0则表示无边. 输出格式 输出一行一个整数,表示该图的连通数. 样例 样 ...