程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> xmu 1466.祖先極值

xmu 1466.祖先極值

編輯:C++入門知識

1466.祖先極值
Time Limit: 5000 MS Memory Limit: 131072 K
Total 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
5
1 2 2 1 3
0 0 1 1 2
4
1 4
2 2
2 3
1 5


Sample Output
1
Wrong request
2
3
唉,我真是太笨了,看了別人的代碼才會做,就是以樹的高度作為區間查詢
妹的,苦逼的調試
[cpp]
#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; 

#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;
}

 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved