9
17
2013
1

【BZOJ3251】树上三角形【倍增】

显然我们要求出每个询问两个点的最近公共祖先。然后我们可以求出其最短路径上的点数。显然,如果要不能构成三角形,那么上面的点权一定是按照大于斐波那契数列排列的,这样在55项左右就超过MAXLONGINT。所以大于等于55一定构成三角形。余下的反正是有50+的点直接SORT一下然后暴力即可。PASCAL的代码又一次又臭又长,居然垫底了。。QAQ

program p3251;
	type
		bian=record
			next,point:int64;
		end;
		arr=array[0..500] of int64;
	var
		f:array[1..111111,0..17] of int64;
		w,d,p:array[1..111111] of int64;
		b:array[1..111111] of bian;
		way:arr;
		len,i,j,q,n,k1,k2,k3:longint;
		ch:char;
		pd:boolean;
	procedure add(k1,k2:int64);
		begin
			inc(len); 
			b[len].point:=k2;
			b[len].next:=p[k1];
			p[k1]:=len;
		end;
	procedure find(k1,k2:int64);
		var
			i,j:longint;
		begin
			d[k1]:=k2;
			i:=p[k1];
			while i<>0 do begin
				find(b[i].point,k2+1);
				i:=b[i].next;
			end;
		end;
	function go_up(k1,k2:int64):int64;
		var
			i,j,k:longint;
		begin
			if k2=0 then exit(k1);
			for k:=0 to 17 do
				if 1 shl k>k2 then break;
			dec(k);
			for i:=0 to k do 
				if k2 and (1 shl i)>0 then k1:=f[k1,i];
			exit(k1);
		end;
	procedure sort(var x:arr;first,en:longint);
		var
			i,j:longint;
		begin
			i:=first; j:=en; x[0]:=x[first];
			while i<j do begin
				while (i<j) and (w[x[j]]>=w[x[0]]) do dec(j);
				if i<j then x[i]:=x[j];
				while (i<j) and (w[x[i]]<w[x[0]]) do inc(i);
				if i<j then x[j]:=x[i];
			end;
			x[i]:=x[0];
			if i>first+1 then sort(x,first,i-1);
			if i<en-1 then sort(x,i+1,en);
		end;	
	function answer(k1,k2:int64):char;
		var
			k,i,j,k3,k4,k5,l:longint;
		begin
			if d[k1]>d[k2] then begin
				i:=k1; k1:=k2; k2:=i;
			end;
			k3:=go_up(k2,d[k2]-d[k1]);
			for k:=0 to 17 do
				if 1 shl k>=d[k3] then break;
			dec(k);
			k4:=k1;
			if k3<>k4 then begin
				for i:=k downto 0 do
					if f[k3,i]<>f[k4,i] then begin
						k3:=f[k3,i];
						k4:=f[k4,i];
					end;
				k3:=f[k3,0];
			end;
			l:=d[k1]-d[k3]+d[k2]-d[k3]+1;
			if (l<3) then exit('N');
			if (l>=55) then exit('Y');
			l:=0;
			i:=k1; 
			while i<>k3 do begin
				inc(l); way[l]:=i; i:=f[i,0];
			end;
			i:=k2; inc(l); way[l]:=i;
			while i<>k3 do begin
				i:=f[i,0]; inc(l); way[l]:=i;
			end;
			sort(way,1,l);
			for i:=3 to l do
				if w[way[i-2]]+w[way[i-1]]>w[way[i]] then exit('Y');
			exit('N');
		end;
	begin
		readln(n,q);
		len:=0;
		fillchar(p,sizeof(p),0);
		fillchar(b,sizeof(b),0);
		fillchar(f,sizeof(f),0);
		for i:=1 to n do
			read(w[i]);
		for i:=1 to n-1 do begin
			readln(k1,k2);
			f[k2,0]:=k1;
			add(k1,k2);
		end;
		find(1,1);
		for i:=1 to 17 do begin
			pd:=false;
			for j:=1 to n do
				if 1 shl i<d[j] then begin
					pd:=true;
					f[j,i]:=f[f[j,i-1],i-1];
				end;
			if pd=false then break;
		end;
		for i:=1 to q do begin
			readln(k1,k2,k3);
			if k1=0 then
				writeln(answer(k2,k3))
			else 
				w[k2]:=k3;
		end;
	end.
Category: 倍增 | Tags: | Read Count: 2772
Avatar_small
pavzi.com 说:
2024年1月17日 20:34

Pavzi.com provides all the news about Gadgets, the Economy, Technology, Business, Finance and many more. The main concept or our aim behind this website has been the will to provide resources with full information on each topic which can be accessed through the Internet. To ensure that every reader gets what is important and worthy about the topic they search and link to hear from us. pavzi.com Our site is a multiple Niche or category website which will ensure to provide information and resources on each and every topic. Some of the evergreen topics you will see on our website are Career, Job Recruitment, Educational, Technology, Reviews and others. We are targeting mostly so it is true that Tech, Finance, and Product Reviews. The only reason we have started this website is to make this site the need for your daily search use.


登录 *


loading captcha image...
(输入验证码)
or Ctrl+Enter

Host by is-Programmer.com | Power by Chito 1.3.3 beta | Theme: Aeros 2.0 by TheBuckmaker.com