• [bzoj4515] [Sdoi2016]游戏


      听说叫李超线段树?...

      加线段(或直线)的操作在http://wenku.baidu.com/link?url=sWGcvUR1m_SwkQ7XeZtMGacA9H7UOcPgYCLNDSSu8YSSClVP11fGN4RNaMwcP5Ltr4HKj10izVldQnvaZRtQ6hvPmFKGfDt0MR_i-YduhX7 里有提到。

      题目就是在区间内加线段,然后问区间内最小值。

      加线段主要是判断优势区间。。

      比较一下新加进来的线段,和原来区间内标记的线段,哪条的优势区间(是较小值的区间)大,就把它作为区间内标记的线段。。

      然后把另外一条下放到它优势的子区间内...继续比较。

      新加的线段最多被分为logn条子线段,每条子线段最多下放logn次。单次插入时间复杂度O(log²n)

      这题强行扔到树上的话那就再写一波链剖了....(记得某年GDKOI出题人也是这么无聊...

      1 #include<cstdio>
      2 #include<iostream>
      3 #include<cstring>
      4 #include<algorithm>
      5 #define ll long long
      6 using namespace std;
      7 const int maxn=100233,mxnode=maxn<<1,mxline=maxn*50;
      8 struct zs{int too,pre,dis;}e[maxn<<1];int tot,last[maxn];
      9 int lc[mxnode],rc[mxnode],id[mxnode],tt;
     10 ll mn[mxnode],dis[maxn];
     11 int dfn[maxn],fa[maxn],dep[maxn],bel[maxn],tim,sz[maxn],disfa[maxn];
     12 ll k[mxline],b[mxline],MN;
     13 int i,j,n,m,cnt,L,R,aa,bb;
     14 ll ST,ST1;
     15  
     16 int ra,fh;char rx;
     17 inline int read(){
     18     rx=getchar(),ra=0,fh=1;
     19     while((rx<'0'||rx>'9')&&rx!='-')rx=getchar();
     20     if(rx=='-')fh=-1,rx=getchar();
     21     while(rx>='0'&&rx<='9')ra*=10,ra+=rx-48,rx=getchar();return ra*fh;
     22 }
     23  
     24 inline ll get(int id,int x){return k[id]*dis[x]+b[id];}
     25 inline void updmn(int x,int a,int b){
     26     if(id[x])
     27         mn[x]=k[id[x]]<0?get(id[x],b):get(id[x],a);//,printf("%d--%d  nowmn:%lld
    ",a,b,mn[x]);
     28     else mn[x]=ST1;
     29     if(a<b)mn[x]=min(mn[x],min(mn[lc[x]],mn[rc[x]]));
     30 }
     31 void upd(int x,int a,int b,int now){
     32     if(L<=a&&R>=b){
     33         if(!id[x]){
     34             id[x]=now,updmn(x,a,b);
     35             return;
     36         }
     37         bool f1=get(id[x],a)<get(now,a),f2=get(id[x],b)<get(now,b),f3;
     38         if(f1==f2||a==b){
     39             if(!f1)id[x]=now,updmn(x,a,b);
     40             return;
     41         }
     42         int mid=a+b>>1;
     43         f3=get(id[x],mid)<get(now,mid);
     44         if(f1==f3)
     45             if(f1)upd(rc[x],mid+1,b,now);
     46             else upd(rc[x],mid+1,b,id[x]),id[x]=now;
     47         else
     48             if(f1)upd(lc[x],a,mid,id[x]),id[x]=now;
     49             else upd(lc[x],a,mid,now);
     50     }else{
     51         int mid=a+b>>1;
     52         if(L<=mid)upd(lc[x],a,mid,now);
     53         if(R>mid)upd(rc[x],mid+1,b,now);
     54     }
     55     updmn(x,a,b);
     56 //  printf("%d--%d  mn:%lld
    ",a,b,mn[x]);
     57 }
     58 void query(int x,int a,int b){
     59     if(id[x])
     60         if(k[id[x]]<0)MN=min(MN,get(id[x],min(b,R)));else MN=min(MN,get(id[x],max(a,L)));
     61     if(L<=a&&R>=b){
     62         MN=min(MN,mn[x]);return;
     63     }
     64     if(a==b)return;
     65     int mid=a+b>>1;
     66     if(L<=mid)query(lc[x],a,mid);
     67     if(R>mid)query(rc[x],mid+1,b);
     68 }
     69  
     70  
     71 void dfs(int x){
     72     sz[x]=1,dep[x]=dep[fa[x]]+1;
     73     for(int i=last[x];i;i=e[i].pre)if(e[i].too!=fa[x])
     74         fa[e[i].too]=x,disfa[e[i].too]=e[i].dis,dfs(e[i].too),sz[x]+=sz[e[i].too];
     75 }
     76 void dfs2(int x,int chain,ll now){
     77     bel[x]=chain,dfn[x]=++tim,dis[tim]=now;
     78     int mx=0,i;
     79     for(i=last[x];i;i=e[i].pre)if(e[i].too!=fa[x]&&sz[e[i].too]>sz[mx])mx=e[i].too;
     80     if(!mx)return;
     81     dfs2(mx,chain,now+disfa[mx]);
     82     for(i=last[x];i;i=e[i].pre)if(e[i].too!=fa[x]&&e[i].too!=mx)dfs2(e[i].too,e[i].too,now+disfa[e[i].too]);
     83 }
     84 inline int getlca(int a,int b){
     85     while(bel[a]!=bel[b]){
     86         if(dep[bel[a]]<dep[bel[b]])swap(a,b);
     87         a=fa[bel[a]];
     88     }
     89     return dep[a]<dep[b]?a:b;
     90 }
     91 inline void insert(int a,int b,int c){
     92     e[++tot].too=b,e[tot].dis=c,e[tot].pre=last[a],last[a]=tot,
     93     e[++tot].too=a,e[tot].dis=c,e[tot].pre=last[b],last[b]=tot;
     94 }
     95  
     96 void build(int a,int b){
     97     int x=++tt;mn[x]=ST;
     98     if(a==b)return;
     99     int mid=a+b>>1;
    100     lc[x]=tt+1,build(a,mid),rc[x]=tt+1,build(mid+1,b);
    101 }
    102  
    103 inline void run_1(int x,int lca){
    104     ST=bb;
    105     while(bel[x]!=bel[lca]){
    106         k[++cnt]=-aa,b[cnt]=ST+aa*dis[dfn[x]],//printf("ST:%lld
    ",ST),
    107         L=dfn[bel[x]],R=dfn[x],upd(1,1,n,cnt),
    108         ST+=1ll*(dis[R]-dis[L]+disfa[bel[x]])*aa,x=fa[bel[x]];
    109     }//printf("tmpst:%lld
    ",ST);
    110     k[++cnt]=-aa,b[cnt]=ST+aa*dis[dfn[x]],//printf("ST:  %lld  k:%lld  b:%lld
    ",ST,k[cnt],b[cnt]),
    111     L=dfn[lca],R=dfn[x],upd(1,1,n,cnt),
    112     ST+=1ll*(dis[R]-dis[L])*aa;
    113 }
    114 inline void run_2(int x,int lca){
    115     ST+=1ll*(dis[dfn[x]]-dis[dfn[lca]])*aa;
    116     while(bel[x]!=bel[lca]){
    117         k[++cnt]=aa,b[cnt]=ST-aa*dis[dfn[x]],//printf("ST:  %lld
    ",ST),
    118         L=dfn[bel[x]],R=dfn[x],upd(1,1,n,cnt),
    119         ST-=1ll*(dis[R]-dis[L]+disfa[bel[x]])*aa,x=fa[bel[x]];
    120     }
    121     if(x!=lca)
    122         k[++cnt]=aa,b[cnt]=ST-aa*dis[dfn[x]],//printf("ST:  %lld
    ",ST),
    123         L=dfn[lca]+1,R=dfn[x],upd(1,1,n,cnt);
    124 }
    125 inline void run_query(int x,int lca){
    126     while(bel[x]!=bel[lca])
    127         L=dfn[bel[x]],R=dfn[x],query(1,1,n),
    128         x=fa[bel[x]];
    129     L=dfn[lca],R=dfn[x],query(1,1,n);
    130 }
    131  
    132 int main(){int id,x,y,lca;
    133     ST=123456789123456789LL;ST1=ST;
    134     n=read(),m=read();
    135     for(i=1;i<n;i++)x=read(),y=read(),insert(x,y,read());
    136     dfs(1),dfs2(1,1,0);
    137 //  for(i=1;i<=n;i++)printf("i:%d  bel:%d    dis:%lld  dfn:%d
    ",i,bel[i],dis[dfn[i]],dfn[i]);
    138     build(1,n);
    139     while(m--){
    140         id=read(),x=read(),y=read(),lca=getlca(x,y);
    141 //      printf("x:%d   y:%d  lca:%d
    ",x,y,lca);
    142         if(id==1)
    143             aa=read(),bb=read(),
    144             run_1(x,lca),run_2(y,lca);
    145         else{
    146             MN=ST1,run_query(x,lca),run_query(y,lca);
    147             printf("%lld
    ",MN);
    148         }
    149     }
    150 //  for(i=1;i<=cnt;i++)printf("line%d:   k:%lld  b:%lld
    ",i,k[i],b[i]);
    151 }
    View Code
  • 相关阅读:
    MINA之心跳协议运用
    基于MINA实现server端心跳检测(KeepAliveFilter)
    求职酸甜苦辣:老陈的几次面试经历
    Java中的装箱与拆箱
    深入解析Apache Mina源码(1)——Mina的过滤器机制实现
    MINA 框架简介
    Java 开发 2.0: 现实世界中的 Redis
    mysql与mongodb、redis的性能对比,包含源代码
    80后之迷茫的一代:为什么都想去当公务员?
    NoSQL一致性
  • 原文地址:https://www.cnblogs.com/czllgzmzl/p/5621638.html
Copyright © 2020-2023  润新知