洛谷 P4092 [HEOI2016/TJOI2016]树 || bzoj4551

https://www.lydsy.com/JudgeOnline/problem.php?id=4551

https://www.luogu.org/problemnew/show/P4092

这当然是树剖裸题,还可以不写线段树用set

(只用set达到一个log是不行的,询问中,中间遇到的路径并不总是整段的轻/重链,可能会有半段的)

  1 #include<cstdio>
  2 #include<algorithm>
  3 #include<cstring>
  4 #include<vector>
  5 #include<set>
  6 using namespace std;
  7 #define fi first
  8 #define se second
  9 #define mp make_pair
 10 #define pb push_back
 11 typedef long long ll;
 12 typedef unsigned long long ull;
 13 typedef pair<int,int> pii;
 14 struct E
 15 {
 16     int to,nxt;
 17 }e[200100];
 18 int f1[100100],ne;
 19 int n,q;
 20 void me(int a,int b)
 21 {
 22     e[++ne].to=b;e[ne].nxt=f1[a];f1[a]=ne;
 23 }
 24 int hson[100100],tp[100100],sz[100100],dp[100100];
 25 int ar[100100],lp[100100],f[100100];
 26 struct Cmp
 27 {
 28     bool operator()(int a,int b)
 29     {
 30         return dp[a]<dp[b];
 31     }
 32 };
 33 set<int,Cmp> t2[100100];//以此点为top的链上所有标记点
 34 void dfs1(int u,int fa)
 35 {
 36     sz[u]=1;
 37     for(int k=f1[u];k;k=e[k].nxt)
 38         if(e[k].to!=fa)
 39         {
 40             dp[e[k].to]=dp[u]+1;
 41             dfs1(e[k].to,u);
 42             sz[u]+=sz[e[k].to];
 43             if(sz[e[k].to]>sz[hson[u]])
 44                 hson[u]=e[k].to;
 45         }
 46 }
 47 void dfs2(int u,int fa)
 48 {
 49     ar[++ar[0]]=u;lp[u]=ar[0];
 50     f[u]=fa;
 51     if(u==hson[fa]) tp[u]=tp[fa];
 52     else    tp[u]=u;
 53     if(hson[u]) dfs2(hson[u],u);
 54     for(int k=f1[u];k;k=e[k].nxt)
 55         if(e[k].to!=fa&&e[k].to!=hson[u])
 56             dfs2(e[k].to,u);
 57 }
 58 int main()
 59 {
 60     int i,a,b;
 61     char tmp[10];
 62     scanf("%d%d",&n,&q);
 63     for(i=1;i<n;i++)
 64     {
 65         scanf("%d%d",&a,&b);
 66         me(a,b);me(b,a);
 67     }
 68     dfs1(1,0);dfs2(1,0);
 69     //for(i=1;i<=n;i++)    printf("%d\n",f[i]);
 70     //puts("b");
 71     //for(i=1;i<=n;i++)    printf("%d\n",ar[i]);
 72     //puts("c");
 73     t2[1].insert(1);//tag[1]=1;
 74     while(q--)
 75     {
 76         scanf("%s",tmp);
 77         if(tmp[0]=='C')
 78         {
 79             scanf("%d",&a);
 80             t2[tp[a]].insert(a);
 81         }
 82         else
 83         {
 84             scanf("%d",&a);
 85             set<int,Cmp>::iterator it;
 86             while(1)
 87             {
 88                 it=t2[tp[a]].upper_bound(a);
 89                 if(it!=t2[tp[a]].begin())
 90                 {
 91                     --it;
 92                     printf("%d\n",*it);
 93                     break;
 94                 }
 95                 a=f[tp[a]];
 96             }
 97         }
 98     }
 99     return 0;
100 }

 

posted @ 2018-08-03 20:07  hehe_54321  阅读(132)  评论(0编辑  收藏  举报
AmazingCounters.com