zoukankan      html  css  js  c++  java
  • UVA 1400."Ray, Pass me the dishes!" -分治+线段树区间合并(常规操作+维护端点)并输出最优的区间的左右端点-(洛谷 小白逛公园 升级版)

    "Ray, Pass me the dishes!"

     UVA - 1400

    题意就是线段树区间子段最大和,线段树区间合并,但是这道题还要求输出最大和的子段的左右端点。要求字典序最小,要求左右端点尽量靠左。

    比如:

    3 3 3 -9 3 3 3

    输出的是1 3,而不是1 7

    3 3 3 -9 3 3 4

    输出的是1 7,而不是5 7

    大体意思就是这样。

    有一个坑,我没读好题,输出Case是每一组样例输出一个,而不是每查询一次就输出一次Case。。。

    其他没什么了。具体代码写了注释。

    代码:

     1 //线段树-线段树区间合并-判断位置
     2 #include<bits/stdc++.h>
     3 using namespace std;
     4 typedef long long ll;
     5 const int maxn=5e5+10;
     6 #define lson l,m,rt<<1
     7 #define rson m+1,r,rt<<1|1
     8 
     9 struct Tree{
    10     ll pre,suf,sub,val;//pre最大前缀和,suf最大后缀和,sub最大子段和,val当前区间和
    11     int lch,rch,lx,rx;//最大子段的左端点,最大子段的右端点,最大前缀和的右端点,最大后缀和的左端点
    12 }tree[maxn<<2];
    13 
    14  Tree pushup(Tree l,Tree r)
    15  {
    16      Tree rt;
    17 //     rt.pre=max(l.pre,l.val+r.pre);
    18 //     rt.suf=max(r.suf,r.val+l.suf);
    19 //     rt.sub=max(max(l.sub,r.sub),l.suf+r.pre);
    20 //根据上面的操作进行变形
    21      if(l.pre>=l.val+r.pre){rt.pre=l.pre;rt.lx=l.lx;}//前缀和
    22      else{rt.pre=l.val+r.pre;rt.lx=r.lx;}
    23      if(r.val+l.suf>=r.suf){rt.suf=r.val+l.suf;rt.rx=l.rx;}//后缀和
    24      else{rt.suf=r.suf;rt.rx=r.rx;}
    25      if(l.sub>=r.sub&&l.sub>=(l.suf+r.pre)){rt.sub=l.sub;rt.lch=l.lch;rt.rch=l.rch;}//子段和
    26      else if((l.suf+r.pre>=l.sub)&&(l.suf+r.pre>=r.sub)){rt.sub=l.suf+r.pre;rt.lch=l.rx;rt.rch=r.lx;}
    27      else{rt.sub=r.sub;rt.lch=r.lch;rt.rch=r.rch;}
    28      rt.val=l.val+r.val;
    29      return rt;
    30  }
    31 
    32  void build(int l,int r,int rt)
    33  {
    34      if(l==r){
    35         scanf("%lld",&tree[rt].val);
    36         tree[rt].pre=tree[rt].suf=tree[rt].sub=tree[rt].val;
    37         tree[rt].lch=tree[rt].rch=tree[rt].lx=tree[rt].rx=l;
    38         return ;
    39      }
    40 
    41      int m=(l+r)>>1;
    42      build(lson);
    43      build(rson);
    44      tree[rt]=pushup(tree[rt<<1],tree[rt<<1|1]);
    45  }
    46 
    47  Tree query(int L,int R,int l,int r,int rt)
    48  {
    49      if(L<=l&&r<=R){
    50         return tree[rt];
    51      }
    52 
    53      int m=(l+r)>>1;
    54      Tree ret,lret,rret;
    55      int flag1=0,flag2=0;
    56      if(L<=m) {lret=query(L,R,lson);flag1=1;}
    57      if(R> m) {rret=query(L,R,rson);flag2=1;}
    58 
    59      if(flag1&&flag2) ret=pushup(lret,rret);
    60      else if(flag1) ret=lret;
    61      else if(flag2) ret=rret;
    62      return ret;
    63  }
    64 
    65  int main()
    66  {
    67      int n,m,cas=0;
    68      while(~scanf("%d%d",&n,&m)){
    69         printf("Case %d:
    ",++cas);
    70         build(1,n,1);
    71         for(int i=1;i<=m;i++){
    72             int l,r;
    73             scanf("%d%d",&l,&r);
    74             Tree ans=query(l,r,1,n,1);
    75             printf("%d %d
    ",ans.lch,ans.rch);
    76         }
    77      }
    78  }

    开溜。

  • 相关阅读:
    python标准库之MultiProcessing库的研究 (1)
    python标准库Beautiful Soup与MongoDb爬喜马拉雅电台的总结
    ASP.NET平台下从浏览器地址栏输入之后发生的事
    async & await 异步编程的一点巧方法
    【MySQL】MySQL一主二从复制环境切换主从库
    【MySQL】MySQL基于二进制文件安装
    【MySQL】MySQL半同步复制
    【MySQL】MySQL搭建主主复制(双主复制/DUAL Master)环境
    【MySQL】MySQL复制
    【MySQL】MySQL搭建主从复制环境
  • 原文地址:https://www.cnblogs.com/ZERO-/p/10679952.html
Copyright © 2011-2022 走看看