主席树+LCA--HDU6723(wls 的树)

题意:http://acm.hdu.edu.cn/showproblem.php?pid=6723

如题。

思路:

http://acm.hdu.edu.cn/showproblem.php?pid=6723 差不多了。

  1 #define IOS ios_base::sync_with_stdio(0); cin.tie(0);
  2 #include <cstdio>//sprintf islower isupper
  3 #include <cstdlib>//malloc  exit strcat itoa system("cls")
  4 #include <iostream>//pair
  5 #include <fstream>//freopen("C:\\Users\\13606\\Desktop\\Input.txt","r",stdin);
  6 #include <bitset>
  7 //#include <map>
  8 //#include<unordered_map>
  9 #include <vector>
 10 #include <stack>
 11 #include <set>
 12 #include <string.h>//strstr substr strcat
 13 #include <string>
 14 #include <time.h>// srand(((unsigned)time(NULL))); Seed n=rand()%10 - 0~9;
 15 #include <cmath>
 16 #include <deque>
 17 #include <queue>//priority_queue<int, vector<int>, greater<int> > q;//less
 18 #include <vector>//emplace_back
 19 //#include <math.h>
 20 #include <cassert>
 21 #include <iomanip>
 22 //#include <windows.h>//reverse(a,a+len);// ~ ! ~ ! floor
 23 #include <algorithm>//sort + unique : sz=unique(b+1,b+n+1)-(b+1);+nth_element(first, nth, last, compare)
 24 using namespace std;//next_permutation(a+1,a+1+n);//prev_permutation
 25 //******************
 26 clock_t __START,__END;
 27 double __TOTALTIME;
 28 void _MS(){__START=clock();}
 29 void _ME(){__END=clock();__TOTALTIME=(double)(__END-__START)/CLOCKS_PER_SEC;cout<<"Time: "<<__TOTALTIME<<" s"<<endl;}
 30 //***********************
 31 #define rint register int
 32 #define fo(a,b,c) for( a=b;a<=c;++a)
 33 #define fr(a,b,c) for( a=b;a>=c;--a)
 34 #define mem(a,b) memset(a,b,sizeof(a))
 35 #define pr printf
 36 #define sc scanf
 37 #define ls rt<<1
 38 #define rs rt<<1|1
 39 typedef pair<int,int> PII;
 40 typedef vector<int> VI;
 41 typedef unsigned long long ull;
 42 typedef long long ll;
 43 typedef double db;
 44 const db E=2.718281828;
 45 const db PI=acos(-1.0);
 46 const ll INF=(1LL<<60);
 47 const int inf=(1<<30);
 48 const db ESP=1e-9;
 49 const int mod=(int)1e9+7;
 50 const int N=(int)2e5+10;
 51 
 52 int tot;
 53 int root[N];//forest_root;
 54 struct node
 55 {
 56     int l,r,sz;
 57 }tr[N*55];//Log(n)
 58 
 59 struct asd
 60 {
 61     int x,fa,len;
 62 }a[N];
 63 //=========================================主席树
 64 int Build(int l,int r)
 65 {
 66     int now=++tot;
 67     tr[now].sz=0;
 68     int mid=(l+r)>>1;
 69     if(l<r)
 70     {
 71         tr[now].l=Build(l,mid);
 72         tr[now].r=Build(mid+1,r);
 73     }
 74     return now;
 75 }
 76 int update(int pre,int l,int r,int x)
 77 {
 78     int now=++tot;
 79     tr[now].sz=tr[pre].sz+1;
 80     tr[now].l=tr[pre].l;
 81     tr[now].r=tr[pre].r;
 82     if(l<r)
 83     {
 84         int mid=(l+r)>>1;
 85         if(x>mid)
 86             tr[now].r=update(tr[pre].r,mid+1,r,x);
 87         else
 88             tr[now].l=update(tr[pre].l,l,mid,x);
 89     }
 90     return now;
 91 }
 92 int Query_big_cnt(int u,int v,int l,int r,int x)
 93 {
 94     if(x==0)return 0;
 95     if(l==r)return 0;//!!!!!!!!!!
 96 
 97     int mid=(l+r)>>1;
 98     int temp=tr[tr[v].r].sz-tr[tr[u].r].sz;
 99     int ans=0;
100     if(x<=mid)
101         ans=Query_big_cnt(tr[u].l,tr[v].l,l,mid,x)+temp;
102     else
103         ans=Query_big_cnt(tr[u].r,tr[v].r,mid+1,r,x);
104     return ans;
105 }
106 int Query_max(int u,int v,int l,int r)
107 {
108     if(l==r)return l;//!!!!!!!!!!
109 
110     int mid=(l+r)>>1;
111     int temp=tr[tr[v].r].sz-tr[tr[u].r].sz;
112     int ans=0;
113     if(!temp)
114         ans=Query_max(tr[u].l,tr[v].l,l,mid);
115     else
116         ans=Query_max(tr[u].r,tr[v].r,mid+1,r);
117     return ans;
118 }
119 //------------------------------------------------MAP
120 class MAP
121 {
122 public:
123     struct EDGE
124     {
125         int to,next;
126         int dis;
127     }edge[N];
128 
129     int tot;
130     int head[N];
131 
132     int dfn[N],DFN,SZ[N];
133     void Init(int n)
134     {
135         tot=DFN=0;
136         for(int i=0;i<=n;++i)
137             head[i]=SZ[i]=dfn[i]=0;
138     }
139     void add(int from,int to,int dis)
140     {
141         ++tot;
142         edge[tot].to=to;
143         edge[tot].dis=dis;
144         edge[tot].next=head[from];
145         head[from]=tot;
146     }
147     int dfs(int u,int fa)
148     {
149         dfn[u]=++DFN;
150         a[DFN]={u,DFN,1};
151         SZ[dfn[u]]=1;
152         for(int i=head[u];i;i=edge[i].next)
153         {
154             int to=edge[i].to;
155             if(to!=fa)
156                 SZ[dfn[u]]+=dfs(to,u);
157         }
158         return SZ[dfn[u]];
159     }
160 }mp;
161 //-----------------------------------------------LCA
162 int fa[N],dis[N],deep[N],P[N][20];
163 
164 void dfs(int now,int pre,int depth)
165 {
166     int i;
167     deep[now]=depth;
168     fa[now]=pre;
169     for(i=mp.head[now];i;i=mp.edge[i].next)
170     {
171         int to=mp.edge[i].to;
172         if(to!=pre)
173         {
174             dis[to]=dis[now]+mp.edge[i].dis;
175             dfs(to,now,depth+1);
176         }
177     }
178 }
179 
180 void init(int n)
181 {
182     int i,j;
183     for(j=0;(1<<j)<=n;j++)
184         fo(i,1,n)
185             P[i][j]=-1;
186 
187     fo(i,1,n)P[i][0]=fa[i];
188 
189     for(j=1;(1<<j)<=n;j++)
190         fo(i,1,n)
191             if(P[i][j-1]!=-1)
192                 P[i][j]=P[P[i][j-1]][j-1];
193 }
194 
195 int LCA(int a,int b)
196 {
197     int i,j;
198     if(deep[a]<deep[b])swap(a,b);
199     for(i=0;(1<<i)<=deep[a];i++);
200     i--;
201 
202     fr(j,i,0)
203         if(deep[a]-(1<<j)>=deep[b])
204             a=P[a][j];
205     if(a==b)return a;
206     fr(j,i,0)
207     {
208         if(P[a][j]!=-1&&P[a][j]!=P[b][j])
209         {
210             a=P[a][j];
211             b=P[b][j];
212         }
213     }
214     return fa[a];
215 }
216 //-------------------------------------------------
217 int find(int x)
218 {
219     while(a[x].fa!=x)
220         x=a[x].fa;
221     return x;
222 }
223 
224 void solve()
225 {
226     int n;
227     sc("%d",&n);
228     tot=0;
229     mp.Init(n);
230     for(int i=1;i<n;++i)
231     {
232         int u,v;
233         sc("%d%d",&u,&v);
234         mp.add(u,v,1);
235         mp.add(v,u,1);
236     }
237     mp.dfs(1,-1);
238     root[0]=Build(1,n);
239     for(int i=1;i<=n;++i)
240         root[i]=update(root[i-1],1,n,a[i].x);
241 
242     dis[1]=0;
243     dfs(1,-1,0);
244     init(n);
245 
246     int m;
247     sc("%d",&m);
248     for(int i=1;i<=m;++i)
249     {
250         int op;
251         sc("%d",&op);
252         if(op==1)
253         {
254             int x;
255             sc("%d",&x);
256             int pos=mp.dfn[x];
257             if(a[pos].fa!=pos)continue;
258             for(int now=pos+a[pos].len;now<=mp.SZ[pos]+pos-1;now+=a[pos].len)
259             {
260                 a[now].fa=pos;
261             }
262             a[pos].len=mp.SZ[pos];
263         }
264         else
265         {
266             int u,v;
267             sc("%d%d",&u,&v);
268             int posu=mp.dfn[u];
269             int posv=mp.dfn[v];
270             int fau=find(posu);
271             int fav=find(posv);
272             int cntu=Query_big_cnt(root[fau-1],root[a[fau].len+fau-1],1,n,u);
273             int cntv=Query_big_cnt(root[fav-1],root[a[fav].len+fav-1],1,n,v);
274             if(fau==fav)
275             {
276                 pr("%d\n",abs(cntu-cntv));
277                 continue;
278             }
279             int len=dis[a[fav].x]+dis[a[fau].x]-2*dis[LCA(a[fau].x,a[fav].x)];
280             len+=cntu+cntv;
281             pr("%d\n",len);
282         }
283     }
284 }
285 
286 int main()
287 {
288     int T;
289     sc("%d",&T);
290     while(T--)solve();
291     return 0;
292 }
293 
294 /**************************************************************************************/

 

posted @ 2020-02-09 19:59  ZMWLxh  阅读(303)  评论(0编辑  收藏  举报