H - The LCIS on the Tree HDU - 4718

The LCIS on the Tree

Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 65535/65535 K (Java/Others)
Total Submission(s): 1615    Accepted Submission(s): 457

题目链接

https://vjudge.net/problem/UVA-12655

Problem Description

For a sequence S1, S2, ... , SN, and a pair of integers (i, j), if 1 <= i <= j <= N and Si < Si+1 < Si+2 < ... < Sj-1 < Sj , then the sequence Si, Si+1, ... , Sj is a CIS (Continuous Increasing Subsequence). The longest CIS of a sequence is called the LCIS (Longest Continuous Increasing Subsequence).
Now
we consider a tree rooted at node 1. Nodes have values. We have Q
queries, each with two nodes u and v. You have to find the shortest path
from u to v. And write down each nodes‘ value on the path, from u to v,
inclusive. Then you will get a sequence, and please show us the length
of its LCIS.

Input

The first line has a number T (T <= 10) , indicating the number of test cases.
For each test case, the first line is a number N (N <= 105), the number of nodes in the tree.
The second line comes with N numbers v1, v2, v3 ... , vN, describing the value of node 1 to node N. (1 <= vi <= 109)
The third line comes with N - 1 numbers p2, p3, p4 ... , pN, describing the father nodes of node 2 to node N. Node 1 is the root and will have no father.
Then comes a number Q, it is the number of queries. (Q <= 105)
For next Q lines, each with two numbers u and v. As described above.

Output

For test case X, output "Case #X:" at the first line.
Then output Q lines, each with an answer to the query.
There should be a blank line *BETWEEN* each test case.

Sample Input

1
5
1 2 3 4 5
1 1 3 3
3
1 5
4 5
2 5

Sample Output

Case #1:
3
2
3

题意

在一棵树上,每次求一条路径最长连续上升子序列。

题解

一开始看错题,以为求最长上升子序列,然后想了好久毫无思路,一看题解发现原来我看错题了。

连续的话就不难了。

树链剖分,然后线段树记录一下该区间最长上升子序列,左端点开始的最长上升子序列长度,右端点。。。

反正就是考虑如果知道左子树和右子树的信息,如何合并。显然合并就是中间可能延长,其他的都一样。

但是在树上,x-->lca(x,y) 和 lca(x,y)-->是不一样的,x-->lca(x,y)需要求最长下降子序列,然后就是一对细节需要处理,具体看代码吧。

代码

  1 #include<bits/stdc++.h>
  2 using namespace std;
  3 #define ll long long
  4 #define N 500050
  5 struct Tree{int l,r,lb,rb,lI,rI,lD,rD,Imx,Dmx;}tr[N<<2];
  6 struct Edge{int from,to,s;}edges[N<<1];
  7 int n,m,cas,w[N];
  8 int tot,last[N];
  9 int cnt,fa[N],dp[N],size[N],son[N],rk[N],kth[N],top[N];
 10 template<typename T>void read(T&x)
 11 {
 12   ll k=0; char c=getchar();
 13   x=0;
 14   while(!isdigit(c)&&c!=EOF)k^=c==‘-‘,c=getchar();
 15   if (c==EOF)exit(0);
 16   while(isdigit(c))x=x*10+c-‘0‘,c=getchar();
 17   x=k?-x:x;
 18 }
 19 void read_char(char &c)
 20 {while(!isalpha(c=getchar())&&c!=EOF);}
 21 void AddEdge(int x,int y)
 22 {
 23   edges[++tot]=Edge{x,y,last[x]};
 24   last[x]=tot;
 25 }
 26 void dfs1(int x,int pre)
 27 {
 28   fa[x]=pre;
 29   dp[x]=dp[pre]+1;
 30   size[x]=1;
 31   son[x]=0;
 32   for(int i=last[x];i;i=edges[i].s)
 33     {
 34       Edge &e=edges[i];
 35       if (e.to==pre)continue;
 36       dfs1(e.to,x);
 37       size[x]+=size[e.to];
 38       if(size[e.to]>size[son[x]])son[x]=e.to;
 39     }
 40 }
 41 void dfs2(int x,int y)
 42 {
 43   rk[x]=++cnt;
 44   kth[cnt]=x;
 45   top[x]=y;
 46   if (son[x]==0)return;
 47   dfs2(son[x],y);
 48   for(int i=last[x];i;i=edges[i].s)
 49     {
 50       Edge &e=edges[i];
 51       if (e.to==fa[x]||e.to==son[x])continue;
 52       dfs2(e.to,e.to);
 53     }
 54 }
 55 void init(Tree &a){a=Tree{0,0,0,0,0,0,0,0,0,0};}
 56 template<typename T>void he(T &c,T a, T b)
 57 {
 58   if (a.Imx==0){c=b;return;}
 59   if (b.Imx==0){c=a;return;}
 60   c.l=a.l; c.r=b.r;
 61   int lena=a.r-a.l+1,lenb=b.r-b.l+1;
 62   c.lb=a.lb; c.rb=b.rb;
 63   c.lI=lena==a.lI&&a.rb<b.lb?lena+b.lI:a.lI;
 64   c.lD=lena==a.lD&&a.rb>b.lb?lena+b.lD:a.lD;
 65   c.rI=lenb==b.rI&&a.rb<b.lb?lenb+a.rI:b.rI;
 66   c.rD=lenb==b.rD&&a.rb>b.lb?lenb+a.rD:b.rD;
 67   c.Imx=max(a.Imx,b.Imx);
 68   c.Imx=max(c.Imx,a.rb<b.lb?a.rI+b.lI:0);
 69   c.Dmx=max(a.Dmx,b.Dmx);
 70   c.Dmx=max(c.Dmx,a.rb>b.lb?a.rD+b.lD:0);
 71 }
 72 void bt(int x,int l,int r)
 73 {
 74   tr[x].l=l; tr[x].r=r;
 75   if (l==r)
 76     {
 77       tr[x]={l,r,w[kth[l]],w[kth[l]],1,1,1,1,1,1};
 78       return;
 79     }
 80   int mid=(l+r)>>1;
 81   bt(x<<1,l,mid);
 82   bt(x<<1|1,mid+1,r);
 83   he(tr[x],tr[x<<1],tr[x<<1|1]);
 84 }
 85 Tree query(int x,int l,int r)
 86 {
 87   if (l<=tr[x].l&&tr[x].r<=r)
 88     return tr[x];
 89   int mid=(tr[x].l+tr[x].r)>>1;
 90   Tree tp1,tp2,tp; init(tp1); init(tp2);
 91   if (l<=mid)tp1=query(x<<1,l,r);
 92   if (mid<r)tp2=query(x<<1|1,l,r);
 93   he(tp,tp1,tp2);
 94   return tp;
 95 }
 96 int get_max(int x,int y)
 97 {
 98   int fx=top[x],fy=top[y],ans=0;
 99   Tree tpx,tpy,tp;
100   init(tpx); init(tpy);
101   while(fx!=fy)
102     {
103       if (dp[fx]>dp[fy])
104     {
105       tp=query(1,rk[fx],rk[x]);
106       he(tpx,tp,tpx);
107       x=fa[fx]; fx=top[x];
108     }
109       else
110     {
111       tp=query(1,rk[fy],rk[y]);
112       he(tpy,tp,tpy);
113       y=fa[fy]; fy=top[y];
114     }
115     }
116   if (dp[x]>dp[y])
117     {
118       tp=query(1,rk[y],rk[x]);
119       he(tpx,tp,tpx);
120     }
121   else
122     {
123       tp=query(1,rk[x],rk[y]);
124       he(tpy,tp,tpy);
125     }
126   ans=max(tpx.Dmx,tpy.Imx);
127   ans=max(ans,tpx.lb<tpy.lb?tpx.lD+tpy.lI:0);
128   return ans;
129 }
130 void work()
131 {
132   if (cas)printf("\n");
133   printf("Case #%d:\n",++cas);
134   read(n);
135   for(int i=1;i<=n;i++)read(w[i]);
136   for(int i=2;i<=n;i++)
137     {
138       int x;
139       read(x);
140       AddEdge(x,i);
141     }
142   dfs1(1,0);
143   dfs2(1,1);
144   bt(1,1,n);
145   read(m);
146   for(int i=1;i<=m;i++)
147     {
148       int x,y;
149       read(x); read(y);
150       printf("%d\n",get_max(x,y));
151     }
152 }
153 void clear()
154 {
155   cnt=0; tot=0;
156   memset(last,0,sizeof(last));
157 }
158 int main()
159 {
160 #ifndef ONLINE_JUDGE
161   freopen("aa.in","r",stdin);
162 #endif
163   int q;
164   read(q);
165   while(q--)
166     {
167       clear();
168       work();
169     }
170 }

原文地址:https://www.cnblogs.com/mmmqqdd/p/10793607.html

时间: 2024-11-14 12:23:34

H - The LCIS on the Tree HDU - 4718的相关文章

HDU 4718 The LCIS on the Tree(树链剖分)

Problem Description For a sequence S1, S2, ... , SN, and a pair of integers (i, j), if 1 <= i <= j <= N and Si < Si+1 < Si+2 < ... < Sj-1 < Sj , then the sequence Si, Si+1, ... , Sj is a CIS(Continuous Increasing Subsequence). The

HDU4718 The LCIS on the Tree(LCT)

又是一枚LCT,写一发加深一下对LCT的理解.本题的坑爹之处就在于,它实在是太坑爹了.询问的是树路径上的最长连续上升的子串,考验的是怎么样去维护.一开始的想法是维护三个变量 ls,rs,mxl,分别表示左起最长上升,右末最长上升,以及总的最长上升,那么最长上升一定是可以在下面的条件下求到的, mxl=max(ch[0]->mxl,ch[1]->mxl) 以及 令temp=1 存一下左右区间的左右lval,rval, if val>ch[0]->rval temp+=ch[0]-&g

hdu 4718 The LCIS on the Tree

题意给你q次询问,给一条链问从给定起点到给定终点的最长连续严格递增子序列. 因为给定起点与终点所以路径可能与dfs序的树节点展开顺序相反.所以问题变成了给n个数询问一个区间的最长LCIS. 但因为方向可正可负,所以我们除了维护区间的最长递增以外还要维护最长递减.线段树的部分就做完了. 树链剖分的时候进行线段树合并,合并的时候右区间取前一个区间,左区间取当前区间.要注意从起点出发的链取最长递减,从终点出发的取最长递增. 当他们来到一条链时,当x比y 的深度更浅这时应该将这段长度与y合并,y比x浅时

H - Can you answer these queries? HDU 4027 (线段树+延迟标记+开根号的速度)

H - Can you answer these queries? Time Limit:2000MS Memory Limit:65768KB 64bit IO Format:%I64d & %I64u Submit Status Practice HDU 4027 Description A lot of battleships of evil are arranged in a line before the battle. Our commander decides to use our

Turing Tree HDU - 3333 (树状数组,离线求区间元素种类数)

After inventing Turing Tree, 3xian always felt boring when solving problems about intervals, because Turing Tree could easily have the solution. As well, wily 3xian made lots of new problems about intervals. So, today, this sick thing happens again..

Mahjong tree (hdu 5379 dfs)

Mahjong tree Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 190    Accepted Submission(s): 58 Problem Description Little sun is an artist. Today he is playing mahjong alone. He suddenly feels

Revenge of Segment Tree (hdu 5086)

Revenge of Segment Tree Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 1282    Accepted Submission(s): 324 Problem Description In computer science, a segment tree is a tree data structure for

AC日记——Dylans loves tree hdu 5274

Dylans loves tree Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)Total Submission(s): 1611    Accepted Submission(s): 388 Problem Description Dylans is given a tree with N nodes. All nodes have a value A[i] .Node

CCPC 2017 哈尔滨 L. Color a Tree &amp;&amp; HDU 6241

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6241 题意:给你一棵有 n 个结点的树,每个结点初始颜色都为白色,有 A 个条件:结点 x_i 的黑色结点数目不少于 y_i 个,同时有 B 个条件,除了结点 x_j 及其子树外至少有 y_j 个结点,求把最少要染成黑色结点的数目使得满足 A + B 个条件. 题解:参考自:https://blog.csdn.net/u013534123/article/details/78523559 #incl