zoukankan      html  css  js  c++  java
  • zoj 3724 Delivery 离线处理+线段树

      1 #include <iostream>
      2 #include <cstdio>
      3 #include <algorithm>
      4 #include <cstring>
      5 #define ll long long
      6 using namespace std;
      7 int n,m,t,tol,tt;
      8 ll f[100010];
      9 ll sum[100010];
     10 struct edge{
     11     int u,v,x;
     12     ll l;
     13     edge(){}
     14     edge(int u,int v,ll l,int x):u(u),v(v),l(l),x(x){}
     15     friend bool operator<(edge a,edge b){
     16         if(a.u!=b.u) return a.u>b.u;
     17         else if(a.v!=b.v) return a.v<b.v;
     18         else return a.x<b.x;
     19     }
     20 }e[800010],te[800010];
     21 struct tree{
     22     int l,r;
     23     ll maxc,lz;
     24 }a[800010];
     25 ll ans[200010];
     26 void build(int l,int r,int k){
     27     a[k].l=l,a[k].r=r;
     28     a[k].maxc=a[k].lz=0;
     29     if(l<r){
     30        int mid=(l+r)>>1;
     31        build(l,mid,k<<1);
     32        build(mid+1,r,k<<1|1);
     33     }
     34 }
     35 void pushdown(int k){
     36     if(a[k].lz!=0){
     37        a[k<<1].maxc=max(a[k].lz,a[k<<1].maxc);
     38        a[k<<1|1].maxc=max(a[k].lz,a[k<<1|1].maxc);
     39        a[k<<1].lz=max(a[k<<1].lz,a[k].lz);
     40        a[k<<1|1].lz=max(a[k<<1|1].lz,a[k].lz);
     41        a[k].lz=0;
     42     }
     43 }
     44 void insert(int l,int r,ll c,int k){
     45     if(l<=a[k].l&&a[k].r<=r){
     46         a[k].maxc=max(a[k].maxc,c);
     47         a[k].lz=max(a[k].lz,c);
     48     }else{
     49         pushdown(k);
     50         int mid=(a[k].l+a[k].r)>>1;
     51         if(r<=mid) insert(l,r,c,k<<1);
     52         else if(l>mid) insert(l,r,c,k<<1|1);
     53         else insert(l,mid,c,k<<1),insert(mid+1,r,c,k<<1|1);
     54         a[k].maxc=max(a[k<<1].maxc,a[k<<1|1].maxc);
     55     }
     56 }
     57 ll query(int l,int r,int k){
     58     if(l<=a[k].l&&a[k].r<=r){
     59         return a[k].maxc;
     60     }else{
     61         pushdown(k);
     62         int mid=(a[k].l+a[k].r)>>1;
     63         if(r<=mid) return query(l,r,k<<1);
     64         else if(l>mid) return query(l,r,k<<1|1);
     65         else return max(query(l,mid,k<<1),query(mid+1,r,k<<1|1));
     66     }
     67 }
     68 void read(){
     69     for(int i=1;i<n;i++) scanf("%lld",&f[i]);
     70     int u,v;
     71     ll l;
     72     tol=tt=0;
     73     f[n]=(ll)1e12;
     74     for(int i=0;i<m;i++){
     75        scanf("%d%d%lld",&u,&v,&l);
     76        if(u==v) continue;
     77        if(u==n&&v==1) f[n]=min(f[n],l);
     78        if(u<v) e[tol++]=edge(u,v,l,0);
     79        else te[tt++]=edge(u,v+n,l,0);
     80     }
     81     scanf("%d",&t);
     82     for(int i=0;i<t;i++){
     83        scanf("%d%d",&u,&v);
     84        if(u<=v) e[tol++]=edge(u,v,(ll)i,1);
     85        else te[tt++]=edge(u,v+n,(ll)i,1);
     86     }
     87 }
     88 void gao(){
     89     sum[0]=0;
     90     for(int i=1;i<n;i++) sum[i]=sum[i-1]+f[i];
     91     sort(e,e+tol);
     92     build(1,n,1);
     93     for(int i=0;i<tol;i++){
     94         if(e[i].x==0){
     95             insert(e[i].v,n,sum[e[i].v-1]-sum[e[i].u-1]-e[i].l,1);
     96         }else{
     97             ans[e[i].l]=sum[e[i].v-1]-sum[e[i].u-1]-query(e[i].u,e[i].v,1);
     98         }
     99     }
    100     sort(te,te+tt);
    101     build(1,2*n-1,1);
    102     for(int i=0;i<tt;i++){
    103         int u=te[i].u,v=te[i].v-n;
    104         if(te[i].x==0){
    105             insert(v+n,2*n-1,f[n]+sum[n-1]-sum[u-1]+sum[v-1]-te[i].l,1);
    106         }else{
    107             ans[te[i].l]=f[n]+sum[n-1]-sum[u-1]+sum[v-1]-query(u,v+n,1);
    108         }
    109     }
    110 }
    111 void out(){
    112     for(int i=0;i<t;i++){
    113         printf("%lld
    ",ans[i]);
    114     }
    115 }
    116 int main(){
    117     while(~scanf("%d%d",&n,&m)){
    118         read();
    119         gao();
    120         out();
    121     }
    122     return 0;
    123 }
    zoj3724

    解题思路:

    由于题目中说短边只会走一次,所以可以发现,往前和往后是不影响的,可以分开讨论。

    然后线段树中记录的走短边的话最多可以省多少,

    离线处理,将修改和询问放一起,先按u从大到小,再按v从小到大排序,以上都一样时,修改优先。

    当u<=v时,插入的线段是[v,n],大小置为u到v的原长度-短边,询问雷同。

    当u>v时,我的做法是将线段树延伸到2*n-1处,那么线段就变为[u,v+n],那么排序和插入的做法和上面一样。

  • 相关阅读:
    BadUSB 利用
    java 将函数作为参数传递
    odoo12 修行提升篇之 常用的高阶函数 (二)
    odoo12 修行提升篇之 异步定时任务 (一)
    odoo12 修行基础篇之 利用kanban做分析 点击跳转分析模型列表 (九)
    odoo12 修行基础篇之 kanban (八)
    odoo12 修行基础篇之 记录批处理 (七)
    odoo12 修行基础篇之 列表的筛选和分组 (六)
    odoo12 修行基础篇之 添加记录编码 (五)
    odoo12 修行基础篇之 添加工作流和操作记录 (四)
  • 原文地址:https://www.cnblogs.com/wonderzy/p/3407646.html
Copyright © 2011-2022 走看看