您的位置:首页 > 其它

算法模板——线段树8 (字符串回文变换)

2015-02-16 00:04 148 查看
实现功能:输入一个长度为N的由26个大写字母组成的字符串,输入M条指令:"1 x y",将x到y的字串重组构成一个字典序最小的回文串,如果不能构成回文串输出False,否则True并完成变换;"2 x y"输出从x到y的子串;"3 x y t"将x到y的所有字全部变成chr(t+64)(即对应大写字母)

原理:用一个数组维护字母个数即可,然后再附带一个带tag的区间覆盖操作,实现回文串的重组

type
vec=array[0..26] of longint;
var
i,j,k,l,m,n,t:longint;
a:array[0..500000] of vec;
b:array[0..500000] of longint;
c:array[0..500000] of ansistring;
function empty:vec;inline;
var a1:vec;
begin
fillchar(a1,sizeof(a1),0);
exit(a1);
end;
function merge(a1,a2:vec):vec;inline;
var i:longint;
begin
for i:=1 to 26 do a1[i]:=a1[i]+a2[i];
exit(a1);
end;
function max(x,y:longint):longint;inline;
begin
if x>y then max:=x else max:=y;
end;
function min(x,y:longint):longint;inline;
begin
if x<y then min:=x else min:=y;
end;
function strr(x:longint;y:char):ansistring;inline;
var s1:ansistring;i:longint;
begin
s1:='';
for i:=1 to x do s1:=s1+y;
exit(s1);
end;
procedure ext(z,x,y:longint);inline;
begin
if b[z]=0 then exit;
if (x<>y) then
begin
b[z*2]:=b[z];
a[z*2]:=empty;
a[z*2][b[z*2]]:=(x+y) div 2-x+1;
c[z*2]:=strr((x+y) div 2-x+1,chr(b[z]+64));
b[z*2+1]:=b[z];
a[z*2+1]:=empty;
a[z*2+1][b[z*2+1]]:=y-(x+y) div 2;
c[z*2+1]:=strr(y-(x+y) div 2,chr(b[z]+64));
end;
a[z]:=empty;
a[z][b[z]]:=y-x+1;
c[z]:=strr(y-x+1,chr(b[z]+64));
b[z]:=0;
end;

procedure built(z,x,y:longint);
var c1:char;
begin
if x=y then
begin
read(c1);c1:=upcase(c1);c[z]:=c1;
a[z]:=empty;a[z][ord(c1)-64]:=1;
end
else
begin
built(z*2,x,(x+y) div 2);
built(z*2+1,(x+y) div 2+1,y);
c[z]:=c[z*2]+c[z*2+1];
a[z]:=merge(a[z*2],a[z*2+1]);
end;
b[z]:=0;
end;
function getsum(z,x,y,l,r:longint):vec;
var a1:vec;
begin
if l>r then exit(empty);
if b[z]>0 then
begin
a1:=empty;
a1[b[z]]:=r-l+1;
exit(a1);
end;
if (x=l) and (y=r) then exit(a[z]);
getsum:=merge(getsum(z*2,x,(x+y) div 2,l,min(r,(x+y) div 2)),getsum(z*2+1,(x+y) div 2+1,y,max((x+y) div 2+1,l),r));
end;
procedure cover(z,x,y,l,r,t:longint);
begin
if l>r then exit;
if (x=l) and (y=r) then
begin
b[z]:=t;
a[z]:=empty;a[z][b[z]]:=r-l+1;
c[z]:=strr(r-l+1,chr(64+b[z]));
exit;
end;
ext(z,x,y);
cover(z*2,x,(x+y) div 2,l,min(r,(x+y) div 2),t);
cover(z*2+1,(x+y) div 2+1,y,max((x+y) div 2+1,l),r,t);
c[z]:=c[z*2]+c[z*2+1];
a[z]:=merge(a[z*2],a[z*2+1]);
end;
function setup(x,y:longint):boolean;
var a1:vec;i,j,k,l:longint;
begin
a1:=getsum(1,1,n,x,y);
l:=0;
for i:=1 to 26 do
if odd(a1[i]) then
if l=0 then l:=i else exit(false);
j:=x;k:=y;
for i:=1 to 26 do
begin
cover(1,1,n,j,j+a1[i] div 2-1,i);
cover(1,1,n,k-a1[i] div 2+1,k,i);
j:=j+a1[i] div 2;k:=k-a1[i] div 2;
end;
if l>0 then cover(1,1,n,j,k,l);
exit(true);
end;
function getstr(z,x,y,l,r:longint):ansistring;inline;
begin
if l>r then exit('');
if b[z]>0 then exit(strr(r-l+1,chr(b[z]+64)));
if (x=l) and (y=r) then exit(c[z]);
exit(getstr(z*2,x,(x+y) div 2,l,min(r,(x+y) div 2))+getstr(z*2+1,(x+y) div 2+1,y,max((x+y) div 2+1,l),r));
end;
begin
readln(n,m);
built(1,1,n);
readln;
for i:=1 to m do
begin
read(t);
case t of
1:begin
readln(j,k);
writeln(setup(j,k));
end;
2:begin
readln(j,k);
writeln(getstr(1,1,n,j,k));
end;
3:begin
readln(j,k,l);
cover(1,1,n,j,k,l);
end;
end;
end;
end.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐