士兵杀敌(四)

时间限制:2000 ms  |  内存限制:65535 KB
难度:5
 
描述

南将军麾下有百万精兵,现已知共有M个士兵,编号为1~M,每次有任务的时候,总会有一批编号连在一起人请战(编号相近的人经常在一块,相互之间比较熟悉),最终他们获得的军功,也将会平分到每个人身上,这样,有时候,计算他们中的哪一个人到底有多少军功就是一个比较困难的事情,军师小工的任务就是在南将军询问他某个人的军功的时候,快速的报出此人的军功,请你编写一个程序来帮助小工吧。

假设起始时所有人的军功都是0.

 
输入
只有一组测试数据。
每一行是两个整数T和M表示共有T条指令,M个士兵。(1<=T,M<=1000000)
随后的T行,每行是一个指令。
指令分为两种:
一种形如
ADD 100 500 55 表示,第100个人到第500个人请战,最终每人平均获得了55军功,每次每人获得的军功数不会超过100,不会低于-100。
第二种形如:
QUERY 300 表示南将军在询问第300个人的军功是多少。
输出
对于每次查询输出此人的军功,每个查询的输出占一行。
样例输入
  1. 4 10
  2. ADD 1 3 10
  3. QUERY 3
  4. ADD 2 6 50
  5. QUERY 3
样例输出
  1. 10
  2. 60
    线段树超时 唉!!明天看看树状数组 先贴上
  3.  
  4. 树状数组点我!!!
  5.  
  6. 树状数组:
  1. #include<stdio.h>
  2. #include<string.h>
  3. #include<queue>
  4. #include<algorithm>
  5. #define MAX 1000010
  6. int n,m;
  7. int sum[MAX<<1];
  8. int lowdit(int x)
  9. {
  10. return x&(-x);//求小于x的最大的2的k次方是多少
  11. }
  12. void update(int x,int a)//更新当前点之前的所有点
  13. {
  14. while(x>0)
  15. {
  16. sum[x]+=a;
  17. x-=lowdit(x);
  18. }
  19. }
  20. int find(int x)//查询当前点
  21. {
  22. int ans=0;
  23. while(x<=m)
  24. {
  25. ans+=sum[x];
  26. x+=lowdit(x);
  27. }
  28. return ans;
  29. }
  30. int main()
  31. {
  32. int j,i;
  33. int a,b,c;
  34. char op[10];
  35. scanf("%d%d",&n,&m);
  36. memset(sum,0,sizeof(sum));
  37. for(i=1;i<=n;i++)
  38. {
  39. scanf("%s",op);
  40. if(op[0]=='A')
  41. {
  42. scanf("%d%d%d",&a,&b,&c);
  43. update(a-1,-c);
  44. update(b,c);
  45. }
  46. else
  47. {
  48. scanf("%d",&a);
  49. printf("%d\n",find(a));
  50. }
  51. }
  52. return 0;
  53. }

  

  1.  
  2. 线段树超时代码:
  1. #include<stdio.h>
  2. #include<string.h>
  3. #include<queue>
  4. #include<algorithm>
  5. #define MAX 1000010
  6. #define INF 0x3f3f3f
  7. int n,m;
  8. int sum[MAX<<2];//记录每个区间的值,即每个气球被标记的次数
  9. int add[MAX<<2];//记录每个对应区间的每个数的值
  10. int ans;
  11. void pushup(int o)//向上传递用来更新每一次被标记区间的值 的改变
  12. {
  13. sum[o]=sum[o<<1]+sum[o<<1|1];
  14. }
  15. void pushdown(int o,int m)//向下传递
  16. {
  17. if(add[o])
  18. {
  19. add[o<<1]+=add[o];
  20. add[o<<1|1]+=add[o];
  21. sum[o<<1]+=add[o]*(m-(m>>1));//线段树左分支的区间长度等于右分支或者比右分支大1
  22. sum[o<<1|1]+=add[o]*(m>>1);
  23. add[o]=0;
  24. }
  25. }
  26. void gettree(int o,int l,int r)//建树
  27. {
  28. sum[o]=add[o]=0;
  29. if(l==r)
  30. return ;
  31. int mid=(l+r)>>1;
  32. gettree(o<<1,l,mid);
  33. gettree(o<<1|1,mid+1,r);
  34. pushup(o);
  35. }
  36. void update(int o,int l,int r,int L,int R,int v)
  37. {
  38. if(L<=l&&R>=r)
  39. {
  40. add[o]+=v;
  41. sum[o]+=v*(r-l+1);
  42. return ;
  43. }
  44. pushdown(o,r-l+1);
  45. int mid=(l+r)>>1;
  46. if(L <= mid)
  47. update(o<<1, l, mid, L ,R,v);
  48. if(R > mid)
  49. update(o<<1|1, mid+1, r, L ,R,v);
  50. pushup(o);//维护区间的值
  51. }
  52. int find(int o,int l,int r,int L,int R)//查找每个气球被修改次数并输出
  53. {
  54. if(L<=l&&R>=r)
  55. {
  56. return sum[o];
  57. }
  58. pushdown(o,r-l+1);
  59. int ans=0;
  60. int mid=(r+l)>>1;
  61. if(L<=mid)
  62. ans+=find(o<<1,l,mid,L,R);
  63. if(R>mid)
  64. ans+=find(o<<1|1,mid+1,r,L,R);
  65. return ans;
  66. }
  67. int main()
  68. {
  69. int n,m,j,i;
  70. int a,b,c;
  71. char op[10];
  72. while(scanf("%d%d",&n,&m)!=EOF)
  73. {
  74. gettree(1,1,n);
  75. for(i=1;i<=n;i++)
  76. {
  77. scanf("%s%d",op,&a);
  78. if(op[0]=='A')
  79. {
  80. scanf("%d%d",&b,&c);
  81. update(1,1,n,a,b,c);
  82. }
  83. else
  84. printf("%lld\n",find(1,1,n,a,a));
  85. }
  86. }
  87. return 0;
  88. }

  

nyoj 123 士兵杀敌(四) 树状数组【单点查询+区间修改】的更多相关文章

  1. NYOJ 116士兵杀敌(二) 树状数组

    题目链接:http://acm.nyist.net/JudgeOnline/problem.php?pid=116 士兵杀敌(一) 数组是固定的,所以可以用一个sum数组来保存每个元素的和就行,但是不 ...

  2. A Simple Problem with Integers 多树状数组分割,区间修改,单点求职。 hdu 4267

    A Simple Problem with Integers Time Limit: 5000/1500 MS (Java/Others)    Memory Limit: 32768/32768 K ...

  3. 题解报告:Luogu P3368 【模板】树状数组 2(区间修改,单点查询)

    题目描述 如题,已知一个数列,你需要进行下面两种操作: 1.将某区间每一个数数加上x 2.求出某一个数的和 输入输出格式 输入格式: 第一行包含两个整数N.M,分别表示该数列数字的个数和操作的总个数. ...

  4. poj 2763 Housewife Wind(树链剖分+单点查询+区间修改)

    题目链接:http://poj.org/problem?id=2763 题意:给一个数,边之间有权值,然后两种操作,第一种:求任意两点的权值和,第二,修改树上两点的权值. 题解:简单的树链剖分. #i ...

  5. Libre OJ 130、131、132 (树状数组 单点修改、区间查询 -> 区间修改,单点查询 -> 区间修改,区间查询)

    这三题均可以用树状数组.分块或线段树来做 #130. 树状数组 1 :单点修改,区间查询 题目链接:https://loj.ac/problem/130 题目描述 这是一道模板题. 给定数列 a[1] ...

  6. NYOJ 231 Apple Tree (树状数组)

    题目链接 描述 There is an apple tree outside of kaka's house. Every autumn, a lot of apples will grow in t ...

  7. POJ 2155 Matrix【二维树状数组+YY(区间计数)】

    题目链接:http://poj.org/problem?id=2155 Matrix Time Limit: 3000MS   Memory Limit: 65536K Total Submissio ...

  8. TZOJ 2725 See you~(二维树状数组单点更新区间查询)

    描述 Now I am leaving hust acm. In the past two and half years, I learned so many knowledge about Algo ...

  9. hdu 2642二维树状数组 单点更新区间查询 模板题

    二维树状数组 单点更新区间查询 模板 从零开始借鉴http://www.2cto.com/kf/201307/227488.html #include<stdio.h> #include& ...

随机推荐

  1. jsonp跨域访问详解

    jsonp是"用来跨域的" 同源策略 首先基于安全的原因,浏览器是存在同源策略这个机制的,同源策略阻止从一个源加载的文档或脚本获取或设置另一个源加载的文档的属性. 1.随便建两个网 ...

  2. 固定滚动外层div的css

    background-color: #2a3138; position: fixed; bottom: 0; left: 0; width: 100%; height: 57px; overflow: ...

  3. rpc远程调用开发

    RPC即远程过程调用,适用于集群管理,集群节点就是RPCServer,而我们发起远程调用的web服务器就是RPCClient.所以是少数rpcClient(可能一个)对多个RPCServer(集群节点 ...

  4. js截取小数点后几位的写法

    截取小数点后几位的方法有很多,下面为大家介绍下使用js是如何实现的 如果${showInfo.tt}的值为20,要要它除以10以后精确到小数点后2位,那么js代码中可作如下写法:  复制代码 代码如下 ...

  5. MySql 在大数量的统计中具体的使用技巧

    一.CASE WHEN THEN ELSE END 使用用法. 在用sql语句统计某字段的某种状态的出现的次数,可以考虑用到 CASE WHEN THEN ELSE END 使用用法.当数据量过于庞大 ...

  6. python 循环while和for in

    #!/uer/bin/env python # _*_ coding: utf-8 _*_ lucknumber = 5 b = 0 while b <3: print('guss count: ...

  7. Xcode 证书生成、设置、应用

    Xcode 证书生成.设置.应用,与大家分享.如果按下面步骤还不能编译成功,我手把手教你. 开发环境: Mac OS lion 10.7.4 XCode 4.3.3 1         点击钥匙图标 ...

  8. 对指定文件生成数字摘要的MD5工具类

    md5特点:压缩性.不可逆性,经常用于传值过程中的值加密或文件加密static char hexdigits[] = { '0', '1', '2', '3', '4', '5', '6', '7', ...

  9. Knockout绑定audio的pause事件导致音频无法停止

    ...时间过得真快, 一晃4天已经过去了, 然而自己并没有动笔写什么. 自省. 看了看今天的工作, 感觉好像没什么可写的. 不禁在想是不是一天一篇有点儿难. 再一想, 这分明就是在给自己找理由. 就是 ...

  10. bzoj2257

    不难发现其实这个捣鼓过程就是一个辗转相减所以最小燃料是瓶容量的最小公约数然后穷举约数即可 ..] of longint; n,k,x,i,m,j,t:longint; procedure sort(l ...