9
14
2013
1

【BZOJ1493】【NOI2007】项链工厂【线段树】

第一次发现线段树可以写得那么高端洋气上档次。旋转和翻转忽略掉,对于每个询问把位置变为原来的位置即可。然后在线段树中记录区间的左界右界,合并的时候如果相等则减一(要注意在C中可能整个串都为同一个颜色,这就不能减)。然后便是裸的区间修改了,瞎搞搞,花了我两天多时间才A掉,细节太复杂,代码写得又臭又长。。。

 

program p1493;
	type
		result=record
			left,right,num:longint;
		end;
	var
		x:array[1..500000] of longint;
		num,left,right,bj:array[1..2000000] of longint;
		xz2,fz,xz,n,q,i,j,c,k1,k2,k3,k:longint;
		p,p1,p2:result;
		ch:char;
	procedure swap(var k1,k2:longint);
		var	
			i:longint;
		begin
			i:=k1; k1:=k2; k2:=i;
		end;
	procedure buildtree(len,l,r:longint);
		var
			i,j:longint;
		begin
			left[len]:=x[l]; right[len]:=x[r];
			if l<>r then begin
				buildtree(len*2,l,(l+r) shr 1);
				buildtree(len*2+1,(l+r) shr 1+1,r);
				num[len]:=num[len*2]+num[len*2+1];
				if left[len*2+1]=right[len*2] then 
					dec(num[len]);
			end else
				num[len]:=1;
		end;
	function changenum(k:longint):longint;
		var	
			i:longint;
		begin
			i:=(k+n-xz) mod n+1;
			if fz=1 then i:=(n+1-i) mod n+1;
			exit(i);
		end;
	function find(k1,k2,k3,k4,k5:longint):result;
		var
			k,i,j:result;
		begin
			if (k2>k5) or (k3<k4) then begin
				k.left:=0; k.right:=0; k.num:=0; exit(k);
			end;
			if bj[k1]<>0 then begin
				k.left:=bj[k1]; k.right:=bj[k1]; k.num:=1; exit(k);
			end;
			if (k2>=k4) and (k3<=k5) then begin
				k.left:=left[k1]; k.right:=right[k1]; k.num:=num[k1]; exit(k);
			end;
			i:=find(k1*2,k2,(k2+k3) shr 1,k4,k5);
			j:=find(k1*2+1,(k2+k3) shr 1+1,k3,k4,k5);
			if i.num=0 then exit(j);
			if j.num=0 then exit(i);
			k.left:=i.left; k.right:=j.right; k.num:=i.num+j.num;
			if (i.right=j.left) and (i.right<>0) then dec(k.num);
			exit(k);
		end;
	procedure maintain(k1,k2,k3:longint);
		begin
			if bj[k1]<>0 then begin
				left[k1]:=bj[k1]; right[k1]:=bj[k1]; num[k1]:=1;
				exit;
			end;
			if k2=k3 then begin
				left[k1]:=x[k2]; right[k1]:=x[k2]; num[k1]:=1;
				exit;
			end;
			left[k1]:=left[k1*2]; right[k1]:=right[2*k1+1];
			num[k1]:=num[k1*2]+num[k1*2+1];
			if left[k1*2+1]=right[k1*2] then 
				dec(num[k1]);
		end;
	procedure changetotal(k1,k2,k3,k4,k5,k6:longint);
		begin
			if (k2>k5) or (k3<k4) then begin maintain(k1,k2,k3); exit; end;
			if (k2>=k4) and (k3<=k5) then
				bj[k1]:=k6
			else begin
				if bj[k1]>0 then begin 
					bj[k1*2]:=bj[k1]; bj[k1*2+1]:=bj[k1]; bj[k1]:=0;
				end;
				changetotal(k1*2,k2,(k2+k3) shr 1,k4,k5,k6);
				changetotal(k1*2+1,(k2+k3) shr 1+1,k3,k4,k5,k6);
			end;
			maintain(k1,k2,k3);
		end;
	function getchar:char;
		var	
			ch:char;
		begin
			read(ch);
			while (ch<'A') or (ch>'Z') do read(ch);
			exit(ch);
		end;
	begin
		readln(n,c);
		fillchar(bj,sizeof(bj),0);
		for i:=1 to n do
			read(x[i]);
		readln;
		buildtree(1,1,n);
		fz:=0; xz:=1;
		readln(q);
		for i:=1 to q do begin
			ch:=getchar;
			if ch='C' then begin
				read(ch);
				if ch='S' then begin
					readln(k1,k2);
					k1:=changenum(k1);
					k2:=changenum(k2);
					if fz=1 then swap(k1,k2);
					if k1>k2 then begin
						p1:=find(1,1,n,k1,n);
						p2:=find(1,1,n,1,k2);
						p.num:=p1.num+p2.num;
						p.left:=p1.left; p.right:=p2.right;
						if p1.right=p2.left then dec(p.num);
					end else begin
						p:=find(1,1,n,k1,k2);
					end;
					writeln(p.num);
				end else begin
					p:=find(1,1,n,1,n);
					if p.left=p.right then dec(p.num);
					if p.num=0 then p.num:=1;
					writeln(p.num);
					{for j:=1 to n do
						write(find(1,1,n,j,j).left,' ');
					readln;}
				end;
			end else if ch='P' then begin
				readln(k1,k2,k3);
				k1:=changenum(k1); k2:=changenum(k2);
				if fz=1 then swap(k1,k2);
				{WRITELN(K1,' ',K2);}
				if k1>k2 then begin
					changetotal(1,1,n,1,k2,k3);
					changetotal(1,1,n,k1,n,k3);
				end else
					changetotal(1,1,n,k1,k2,k3);
			end else if ch='S' then begin
				readln(k1,k2);
				k1:=changenum(k1); k2:=changenum(k2);
				if fz=1 then swap(k1,k2);
				{WRITELN(K1,' ',K2);}
				j:=find(1,1,n,k1,k1).left;
				k:=find(1,1,n,k2,k2).left;
				changetotal(1,1,n,k1,k1,k);
				changetotal(1,1,n,k2,k2,j);
			end else if ch='F' then begin
				fz:=(fz+1) mod 2;
				xz:=(n+1-xz) mod n+1;
			end else begin
				readln(k1);
				xz:=(xz+k1-1) mod n+1;
			end;
		end;
	end.
Category: 数据结构 | Tags: | Read Count: 2174
Avatar_small
boardmodelpaper.com 说:
2024年1月17日 20:36

The Board model paper" typically refers to a sample or model question paper that is designed by educational boards or institutions for various exams. These papers serve as practice material for students preparing for exams, providing them with an idea of the question format, difficulty level, and the type of content that may be covered in the actual examination. boardmodelpaper.com Model papers are usually created for specific subjects or courses. They cover a range of topics and chapters that students are expected to have studied during the academic term. Students often use these educational board model papers as an integral part of their exam preparation strategy, helping them familiarize themselves with the exam pattern and refine their understanding of the subject matter.


登录 *


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