主席树+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 /**************************************************************************************/