节点树xmu 1466.祖先极值
生活随笔
收集整理的這篇文章主要介紹了
节点树xmu 1466.祖先极值
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
首先聲明,我是一個菜鳥。一下文章中出現技術誤導情況蓋不負責
????
1466.先人極值 Time Limit: 5000 MS Memory Limit: 131072 KTotal Submissions: 153 (39 users) Accepted: 43 (25 users)
[ My Solution]
????
Description????
在一棵有向樹中, 若節點u至節點v之間有一條有向邊, 則我們稱u為v的父節點, 也可以稱作1先人節點。所謂節點v的k先人節點, 指的是節點v的父節點的k-1先人節點。當初, 給定你一棵以0為根節點的樹, 樹上的每一個節點都有一個值, 你需要能快速的回答出從節點v至它的k先人節點所經過的全部節點中(即v節點、v節點的1先人、...、v節點的k-1先人、v節點的k先人), 值最大的節點的值的為多少? 其中我們默認0號節點的值為0。????
Input????
輸入的第一行有一個正整數n (n <= 100,000), 接下來的一行有n個整數ai(1 <= i <= n, 1 <= ai <= 1,000,000,000), 第i個數字代表了第i號節點上的數值。再接下來的一行有n個正整數bi(1 <= i <= n, 0 <= bi < i), 第i個數字代表了第i號節點的父節點的為bi。再接下來有一個整數m (1 <= m <= 100,000), 代表了詢問的次數, 接下來的m行, 每行有2個整數k, v (1 <= k <= n, 1 <= v <= n), 代表了詢問, 從v節點到它的k先人所閱歷的全部節點中的最大值。????
Output????
對于每次詢問, 若v節點不存在k先人, 則輸出一行"Wrong request", 否則輸出一個整數, 代表了從v節點到它的k先人所閱歷的全部節點中的最大值。????
Sample Input????
51 2 2 1 3
0 0 1 1 2
4
1 4
2 2
2 3
1 5
????
Sample Output????
1Wrong request
2
3
????
唉,我真是太笨了,看了別人的代碼才會做,就是以樹的高度作為區間查詢????
妹的,苦逼的調試 每日一道理時間好比一條小溪,它能招引我們奔向生活的海洋;時間如同一葉扁舟,它將幫助我們駛向理想的彼岸;時間猶如一支畫筆,它會指點我們描繪人生的畫卷。
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<vector> using namespace std; #define N 100010 #define l(i) i<<1 #define r(i) i<<1|1 struct node{int l,r,mx; }T[N*4]; int mx; struct Data{int x,id; }; int v[N],ans[N];//值,答案 vector<Data>a[N]; vector<int>son[N]; void build(int l,int r,int k){T[k].l=l;T[k].r=r;T[k].mx=0;if(l==r)return;int mid=(l+r)/2;build(l,mid,l(k));build(mid+1,r,r(k)); } int insert(int d,int k,int v){//值k插入區間[d,d]if(T[k].l==T[k].r)return T[k].mx=v;int ll=l(k);int rr=r(k);if(T[ll].r>=d)insert(d,ll,v);//往左else if(T[rr].l<=d) insert(d,rr,v);//往右return T[k].mx=max(T[ll].mx,T[rr].mx); } void query(int l,int r,int k){//查詢區間[l,r]if(T[k].l==l&&T[k].r==r){mx=max(mx,T[k].mx);return;}int ll=l(k);int rr=r(k);if(T[ll].r>=r)query(l,r,ll);//往左else if(T[rr].l<=l)query(l,r,rr);//往右else{query(l,T[ll].r,ll);//往左query(T[rr].l,r,rr);//往右} } void dfs(int x,int d){int i,j,k;insert(d,1,v[x]);//插入v//cout<<"插入"<<x<<" "<<v[x]<<endl;for(i=0;i<a[x].size();i++){//查詢x結點k=d-a[x][i].x;mx=-1;if(k>=0)query(k,d,1);ans[a[x][i].id]=mx;//cout<<x<<" "<<k<<" "<<d<<" "<<mx<<endl;}for(i=0;i<son[x].size();i++)//遍歷兒子dfs(son[x][i],d+1);//遞歸遍歷 } int main(){int n,i,j,k;v[0]=0;struct Data s;while(scanf("%d",&n)!=EOF){memset(a,0,sizeof(a));memset(son,0,sizeof(son));build(0,n-1,1);//建立空樹for(i=1;i<=n;i++)scanf("%d",&v[i]);for(i=1;i<=n;i++){scanf("%d",&j);son[j].push_back(i);//i是j的兒子}scanf("%d",&n);for(i=0;i<n;i++){scanf("%d%d",&j,&k);s.x=j;s.id=i;a[k].push_back(s);}/*for(i=0;i<=n;i++){cout<<i<<":";for(j=0;j<son[i].size();j++){cout<<son[i][j]<<" ";}cout<<endl;}*/dfs(0,0);//從根遍歷到最后for(i=0;i<n;i++)if(ans[i]==-1)printf("Wrong request\n");else printf("%d\n",ans[i]);} return 0; }
文章結束給大家分享下程序員的一些笑話語錄: 騰訊的動作好快,2010年3月5日19時28分58秒,QQ同時在線人數1億!剛剛看到編輯發布的文章,相差才2分鐘,然后連專題頁面都做出來了,他們早就預料到了吧?(其實,每人贈送10Q幣,輕輕松松上兩億!)
總結
以上是生活随笔為你收集整理的节点树xmu 1466.祖先极值的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: java 面试题解惑一 类的初始化顺
- 下一篇: 无线电频段属国家资源,不是你想用就能用