码迷,mamicode.com
首页 > 其他好文 > 详细

数据结构(树链剖分):NOI2014 购票

时间:2016-05-14 10:16:54      阅读:124      评论:0      收藏:0      [点我收藏+]

标签:

技术分享

 

 技术分享

技术分享  用线段树优化凸包。

  注意以下细节:

    1.必须先递归非重儿子,若先递归重儿子,可能会把有用解踢掉。

    2.不能每条链只建一个凸包,因为凸包不能只用某一部分去更新答案(可能不在考虑范围中的点联合某点踢掉了最优的点)。

  还有就是老实地用double比斜率吧,不然爆long long。

  1 #include <algorithm>
  2 #include <iostream>
  3 #include <cstring>
  4 #include <cstdio>
  5 #include <vector>
  6 using namespace std;
  7 const long long INF=(long long)1e18;
  8 const int maxn=200010;
  9 int cnt,fir[maxn],to[maxn],nxt[maxn],son[maxn],sz[maxn],fa[maxn],n,t;
 10 long long val[maxn],P[maxn],Q[maxn],S[maxn],F[maxn],L[maxn];
 11 void addedge(int a,int b,long long c){
 12     nxt[++cnt]=fir[a];fir[a]=cnt;to[cnt]=b;val[cnt]=c;
 13 }
 14 
 15 void DFS(int x){
 16     sz[x]=1;
 17     for(int i=fir[x];i;i=nxt[i])
 18         if(to[i]!=fa[x]){
 19             fa[to[i]]=x;
 20             S[to[i]]=S[x]+val[i];
 21             DFS(to[i]);
 22             sz[x]+=sz[to[i]];
 23             if(sz[son[x]]<sz[to[i]])
 24                 son[x]=to[i];
 25         }
 26 }
 27 
 28 int top[maxn],ID[maxn],RID[maxn],tot;
 29 void DFS(int x,int tp){
 30     ID[x]=++tot;RID[tot]=x;top[x]=tp;
 31     if(son[x])DFS(son[x],tp);
 32     for(int i=fir[x];i;i=nxt[i])
 33         if(to[i]!=fa[x]&&to[i]!=son[x])
 34             DFS(to[i],to[i]);
 35 }
 36 
 37 struct Slope{
 38     vector<int>id;
 39     void Insert(int x){
 40         int p=id.size()-1;
 41         id.push_back(x);
 42         while(true){
 43             if(p<=0)break;
 44             if(1.0*(F[id[p]]-F[id[p-1]])/(S[id[p]]-S[id[p-1]])<1.0*(F[id[p+1]]-F[id[p]])/(S[id[p+1]]-S[id[p]]))break;
 45             id.pop_back();id.pop_back();id.push_back(x);p--;
 46         }
 47         return; 
 48     }
 49     
 50     long long Query(int p){
 51         int p1=-1,p2;
 52         for(int i=20;i>=0;i--){
 53             p2=p1+(1<<i);
 54             if(p2>=id.size()-1)continue;
 55             if(1.0*(F[id[p2+1]]-F[id[p2]])/P[p]<=1.0*(S[id[p2+1]]-S[id[p2]]))
 56                 p1+=1<<i;
 57         }
 58         p1+=1;
 59         return F[id[p1]]+(S[p]-S[id[p1]])*P[p]+Q[p];
 60     }
 61 }slope[maxn<<2];
 62 
 63 long long Query(int x,int l,int r,int a,int b,int p){
 64     if(l>=a&&r<=b)
 65         return slope[x].Query(p);
 66         
 67     int mid=(l+r)>>1;
 68     long long ret=INF;
 69     if(a<=mid)
 70         ret=Query(x<<1,l,mid,a,b,p);
 71     if(mid<b)
 72         ret=min(ret,Query(x<<1|1,mid+1,r,a,b,p));
 73     return ret;        
 74 }
 75 
 76 void Insert(int x,int l,int r,int p){
 77     slope[x].Insert(p);
 78     if(l==r)return;
 79     int mid=(l+r)>>1;
 80     if(mid>=ID[p])
 81         Insert(x<<1,l,mid,p);
 82     else
 83         Insert(x<<1|1,mid+1,r,p);    
 84 }
 85 
 86 long long Get_ans(int p){ 
 87     int pos=fa[p];
 88     long long ret=INF;
 89     while(pos){
 90         if(S[p]-L[p]>S[pos])break;
 91         int p1=ID[top[pos]]-1;
 92         for(int i=20;i>=0;i--)
 93             if(p1+(1<<i)<ID[pos]&&S[RID[p1+(1<<i)]]<S[p]-L[p])
 94                 p1+=1<<i;        
 95         ret=min(ret,Query(1,1,n,p1+1,ID[pos],p));
 96         pos=fa[top[pos]];
 97     }
 98     return ret;
 99 }
100 
101 void Solve(int x){
102     F[x]=x==1?0:Get_ans(x);
103     Insert(1,1,n,x);
104     for(int i=fir[x];i;i=nxt[i])
105         if(to[i]!=son[x])
106             Solve(to[i]);
107     if(son[x])
108         Solve(son[x]);        
109     return;
110 }
111 
112 int main(){
113 #ifndef ONLINE_JUDGE 
114     freopen("ticket.in","r",stdin);
115     freopen("ticket.out","w",stdout);
116 #endif 
117     scanf("%d%d",&n,&t);
118     for(int i=2,a,b;i<=n;i++){
119         scanf("%d%d%lld%lld%lld",&a,&b,&P[i],&Q[i],&L[i]);
120         addedge(a,i,b*1ll);
121     }
122     
123     DFS(1);
124     DFS(1,1);
125     
126     Solve(1);
127     for(int i=2;i<=n;i++)
128         printf("%lld\n",F[i]);
129     return 0;
130 }

 

数据结构(树链剖分):NOI2014 购票

标签:

原文地址:http://www.cnblogs.com/TenderRun/p/5491960.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!