题意:给你一个序列,支持两种操作:单点修改;询问一个区间中所有相邻位置下标奇偶性均不同的子序列中,和最大的是多少。

线段树每个结点维护四个值:

以奇数下标开始到奇数下标结束的最大子序列和;

以偶数下标开始到偶数下标结束的最大子序列和;

以奇数下标开始到偶数下标结束的最大子序列和;

以偶数下标开始到奇数下标结束的最大子序列和。

合并的时候先在左右两区间中取较大者,然后奇-偶的答案能通过奇-奇+偶-偶、奇-偶+奇-偶得到;奇-奇的答案能通过奇-奇+偶-奇、奇-偶+奇-奇得到……这样讨论一下。

  1. #include<cstdio>
  2. #include<algorithm>
  3. using namespace std;
  4. int ss[4][2][2];
  5. typedef long long ll;
  6. const ll INF=1000000000000000ll;
  7. int n,m;
  8. struct data{
  9. ll x[4];
  10. data(const ll &x,const ll &y,const ll &z,const ll &w){
  11. this->x[0]=x;
  12. this->x[1]=y;
  13. this->x[2]=z;
  14. this->x[3]=w;
  15. }
  16. data(){}
  17. ll maxx(){
  18. return max(x[0],max(x[1],max(x[2],x[3])));
  19. }
  20. };
  21. data sumv[400005];
  22. data pushup(data ls,data rs){
  23. data res;
  24. for(int i=0;i<4;++i){
  25. res.x[i]=max(ls.x[i],rs.x[i]);
  26. for(int j=0;j<2;++j){
  27. if(ls.x[ss[i][j][0]]>-INF && rs.x[ss[i][j][1]]>-INF){
  28. res.x[i]=max(res.x[i],ls.x[ss[i][j][0]]+rs.x[ss[i][j][1]]);
  29. }
  30. }
  31. }
  32. return res;
  33. }
  34. void buildtree(int rt,int l,int r){
  35. if(l==r){
  36. ll t;
  37. if(l&1){
  38. scanf("%lld",&t);
  39. sumv[rt]=data(t,-INF,-INF,-INF);
  40. }
  41. else{
  42. scanf("%lld",&t);
  43. sumv[rt]=data(-INF,t,-INF,-INF);
  44. }
  45. return;
  46. }
  47. int m=(l+r>>1);
  48. buildtree(rt<<1,l,m);
  49. buildtree(rt<<1|1,m+1,r);
  50. sumv[rt]=pushup(sumv[rt<<1],sumv[rt<<1|1]);
  51. }
  52. void update(int p,ll v,int rt,int l,int r){
  53. if(l==r){
  54. if(l&1){
  55. sumv[rt]=data(v,-INF,-INF,-INF);
  56. }
  57. else{
  58. sumv[rt]=data(-INF,v,-INF,-INF);
  59. }
  60. return;
  61. }
  62. int m=(l+r>>1);
  63. if(p<=m){
  64. update(p,v,rt<<1,l,m);
  65. }
  66. else{
  67. update(p,v,rt<<1|1,m+1,r);
  68. }
  69. sumv[rt]=pushup(sumv[rt<<1],sumv[rt<<1|1]);
  70. }
  71. data query(int ql,int qr,int rt,int l,int r){
  72. if(ql<=l && r<=qr){
  73. return sumv[rt];
  74. }
  75. int m=(l+r>>1);
  76. data res;
  77. if(ql<=m && m<qr){
  78. res=pushup(query(ql,qr,rt<<1,l,m),query(ql,qr,rt<<1|1,m+1,r));
  79. }
  80. else if(ql<=m){
  81. res=query(ql,qr,rt<<1,l,m);
  82. }
  83. else{
  84. res=query(ql,qr,rt<<1|1,m+1,r);
  85. }
  86. return res;
  87. }
  88. int main(){
  89. // freopen("j.in","r",stdin);
  90. ss[0][0][0]=0; ss[0][0][1]=3; ss[0][1][0]=2; ss[0][1][1]=0;
  91. ss[1][0][0]=1; ss[1][0][1]=2; ss[1][1][0]=3; ss[1][1][1]=1;
  92. ss[2][0][0]=0; ss[2][0][1]=1; ss[2][1][0]=2; ss[2][1][1]=2;
  93. ss[3][0][0]=1; ss[3][0][1]=0; ss[3][1][0]=3; ss[3][1][1]=3;
  94. scanf("%d%d",&n,&m);
  95. buildtree(1,1,n);
  96. int op,x,y;
  97. for(int i=1;i<=m;++i){
  98. scanf("%d%d%d",&op,&x,&y);
  99. if(op!=1){
  100. printf("%lld\n",query(x,y,1,1,n).maxx());
  101. }
  102. else{
  103. update(x,y,1,1,n);
  104. }
  105. }
  106. return 0;
  107. }

【线段树】XIII Open Championship of Y.Kupala Grodno SU Grodno, Saturday, April 29, 2017 Problem J. Jedi Training的更多相关文章

  1. 【贪心】【后缀自动机】XIII Open Championship of Y.Kupala Grodno SU Grodno, Saturday, April 29, 2017 Problem E. Enter the Word

    题意:给你一个串,让你从左到右构造这个串,一次操作可以直接在当前串后面添加一个任意字符,或者拷贝当前串的任意一个子串到当前串的后面.问你最少要多少次操作才能构造出这个串. 从前向后贪心,从当前已构造的 ...

  2. 【DFS】XIII Open Championship of Y.Kupala Grodno SU Grodno, Saturday, April 29, 2017 Problem D. Divisibility Game

    题意:给你一个序列,长度不超过52,每个元素不超过13.让你重新对这个序列排序,sum(i)表示i的前缀和,使得排序过后,对每个i,都有sum(i)%i==0. 深搜,加两个优化:①倒着从后向前搜:② ...

  3. 【二分】【三分】【计算几何】XIII Open Championship of Y.Kupala Grodno SU Grodno, Saturday, April 29, 2017 Problem L. Lines and Polygon

    题意:给你一个凸多边形,和多次询问,每次询问给你一条直线,问你这条直线与凸包上的顶点的最近距离是多少. 记当前询问的直线的斜率为K, 先找到与这条直线距离最远的两个点: 就把凸包所有的边当做有向直线进 ...

  4. 【线段树成段更新成段查询模板】【POJ3468】A Simple Problem with Integerst

    题目大意: 2个操作 A.区间a b 增加 c B 查询a b; 注意事项:1.记住要清除标记 2.查询时要下放标记,但没必要向上更新 线段:自带的,不用建模 区间和性质:sum: /* WA 1次 ...

  5. 【构造】Ural Championship April 30, 2017 Problem K. King’s island

    题意:让你构造一个n个点的简单多边形,使得所有点是整点,并且所有边长是整数,并且没有边平行于坐标轴. 就利用勾股数,如下图这样构造即可,n为偶数时,只需矩形拼成,n为奇数时,封上虚线边即可. #inc ...

  6. 【哈希表】Ural Championship April 30, 2017 Problem H. Hamburgers

    题意:有n群人,每个人有喜欢的汉堡配方:有m家店,给出每家店的每个汉堡的配方,如果存在某个汉堡,其配料表包含某个人喜欢的配方,则这个人喜欢这个汉堡所在的店家.问你对每群人,输出被喜欢的人数最多的店面是 ...

  7. 【折半枚举】Ural Championship April 30, 2017 Problem G. Glasses with solutions

    题意:有n杯盐溶液,给定每杯里面盐的质量以及盐溶液的质量.问你有多少种方案选择一个子集,使得集合里面的盐溶液倒到一个被子里面以后,浓度为A/B. 折半枚举,暴力搜索分界线一侧的答案数,跨越分界线的答案 ...

  8. codeforce ABBYY Cup 3.0 - Finals (online version) B2. Shave Beaver! 线段树

    B2. Shave Beaver!   The Smart Beaver has recently designed and built an innovative nanotechnologic a ...

  9. XIII Open Grodno SU Championship

    A. Alice in the Wonderland 按题意模拟. #include<stdio.h> #include<iostream> #include<strin ...

随机推荐

  1. 【洛谷 P2303】 [SDOi2012]Longge的问题 (欧拉函数)

    题目链接 题意:求\(\sum_{i=1}^{n}\gcd(i,n)\) 首先可以肯定,\(\gcd(i,n)|n\). 所以设\(t(x)\)表示\(gcd(i,n)=x\)的\(i\)的个数. 那 ...

  2. Python模块学习 - Fileinput

    Fileinput模块 fileinput是python提供的标准库,使用fileinput模块可以依次读取命令行参数中给出的多个文件.也就是说,它可以遍历 sys.argv[1:],并按行读取列表中 ...

  3. Python3 xml模块的增删改查

    xml数据示例 ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 <data>     < ...

  4. linux网络编程之IO函数

    Linux操作系统中的IO函数主要有read(),write(),recv(),send(),recvmsg(),sendmsg(),readv(),writev(). 接收数据的recv()函数 # ...

  5. Centos_Lvm_Create pv vg lv and mount

    re-scan new disks without restarting CentOS re-scan new disks(/dev/sdc): #ls /sys/class/scsi_host/ h ...

  6. mybatis-plus的学习

    1.mybatisplus 提供了比较齐全的crud即增删改查,不需要在mapper.xml里写sql可以直接调用 原文链接:http://blog.csdn.net/u014519194/artic ...

  7. leetcode之Ransom Note

    题目描述: 
Given
 an 
arbitrary
 ransom
 note
 string 
and 
another 
string 
containing 
letters from
 a ...

  8. Leetcode 之Evaluate Reverse Polish Notation(41)

    很简单的一道题,定义一个栈保留操作数,遇操作符则弹出运算即可. bool isOperator(string &op) { //注意用法 && string("+-* ...

  9. html,获取iframe的window,document,自定事件与iframe通信

      获取iframe的window对象js代码如下.注意:一定要在文档加载完成之后,才能获取到 var Iframe=document.getElementById("script" ...

  10. 百度之星资格赛--IP聚合

    IP聚合 Accepts: 1901 Submissions: 4979 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/6553 ...