spoj,gss系列
Spoj 1034 gss 1
给出n个数,然后q组询问,每组询问x,y,表示求区间[x, y]内的最大连续和是多少
解:线段树,写得很挫,复杂度高死了,有空收集一些高效程序来研究
1 //spoj gss 1 ... 2 const 3 maxn=50011; 4 inf='1.txt'; 5 type 6 type_node=record 7 sonl, sonr, l, r, mid, max, sul, sur, sum: longint; 8 end; 9 var 10 tree: array[0..maxn*4]of type_node; 11 a: array[0..maxn]of longint; 12 n, q, x, y: longint; 13 procedure build(k, xx, yy: longint); 14 begin 15 with tree[k] do begin 16 l := xx; r := yy; 17 mid := (l+r)>>1; 18 if l=r then begin 19 sum := a[l]; max := a[l]; sul := a[l]; sur := a[l]; 20 sonl := 0; sonr := 0; 21 exit; 22 end; 23 sonl := k << 1; sonr := sonl + 1; 24 build(sonl, xx, mid); 25 build(sonr, mid+1, yy); 26 sum := tree[sonl].sum + tree[sonr].sum; 27 if ((tree[sonl].sul)>(tree[sonl].sum+tree[sonr].sul)) then sul := tree[sonl].sul 28 else sul := tree[sonl].sum+tree[sonr].sul; 29 if ((tree[sonr].sur)>(tree[sonr].sum+tree[sonl].sur)) then sur := tree[sonr].sur 30 else sur := tree[sonr].sum+tree[sonl].sur; 31 if (tree[sonl].max>tree[sonr].max) then max := tree[sonl].max 32 else max := tree[sonr].max; 33 if (max<tree[sonl].sur+tree[sonr].sul) then max := tree[sonl].sur+tree[sonr].sul; 34 end; 35 end; 36 37 function askr(k, xx, yy: longint): longint; 38 var 39 tmp: longint; 40 begin 41 while (xx>tree[k].mid)and(tree[k].sonl<>0) do k := tree[k].sonr; 42 with tree[k] do begin 43 if (xx=l)and(r=yy) then exit(sur); 44 askr := tree[sonr].sur; 45 tmp := tree[sonr].sum + {tree[sonl].sur}askr(sonl, xx, mid); 46 if tmp>askr then askr := tmp; {1 wa} 47 end; 48 end; 49 50 function askl(k, xx, yy: longint): longint; 51 var 52 tmp: longint; 53 begin 54 while (yy<=tree[k].mid)and(tree[k].sonl<>0) do k := tree[k].sonl; 55 with tree[k] do begin 56 if (l=xx)and(r=yy) then exit(sul); 57 askl := tree[sonl].sul; 58 tmp := tree[sonl].sum + {tree[sonr].sul}askl(sonr, mid+1, yy); 59 if tmp>askl then askl := tmp; 60 end; 61 end; 62 63 function query(k, xx, yy: longint): longint; 64 var 65 tmp: longint; 66 begin 67 query := -maxlongint; 68 with tree[k] do begin 69 if (xx<=l)and(r<=yy) then exit(max); 70 if yy<=mid then query := query(sonl, xx, yy) 71 else if xx>mid then query := query(sonr, xx, yy) 72 else begin 73 tmp := query(sonl, xx, mid); 74 if query<tmp then query := tmp; 75 tmp := query(sonr, mid+1, yy); 76 if query<tmp then query := tmp; 77 tmp := askr(sonl, xx, mid) + askl(sonr, mid+1, yy); 78 if query<tmp then query := tmp; 79 end; 80 end; 81 end; 82 83 procedure init; 84 var 85 i: longint; 86 begin 87 readln(n); 88 for i := 1 to n do read(a[i]); readln; 89 fillchar(tree, sizeof(tree[0]), 0); 90 build(1, 1, n); 91 end; 92 93 procedure main; 94 var 95 i: longint; 96 begin 97 readln(q); 98 for i := 1 to q do begin 99 readln(x, y); 100 writeln(query(1, x, y)); 101 end; 102 end; 103 104 begin 105 //assign(input,inf); reset(input); 106 init; 107 main; 108 end.
Spoj 1716 gss3
题意同gss1,只是增加了修改数的操作
解:同gss1,+个修改数的操作,另外自己以后写程序注意把跳出语句放在前面(放在更新语句后),202调起来很蛋疼,fp老是开开关关的..
1 //orzorzorz 2 const 3 maxn=50011; 4 inf='1.txt'; 5 type 6 type_node=record 7 l, r, mid, sonl, sonr, max, sum, sul, sur: longint; 8 end; 9 var 10 tree: array[0..maxn*4]of type_node; 11 a: array[0..maxn]of longint; 12 x, y, n, m: longint; 13 14 procedure build(k, ll, rr: longint); 15 var 16 tmp: longint; 17 begin 18 with tree[k] do begin 19 l := ll; r := rr; mid := (l+r)>>1; 20 if ll=rr then begin 21 sum := a[l]; max := a[l]; sul := a[l]; sur := a[l]; 22 sonl := 0; sonr := 0; 23 exit; 24 end; 25 sonl := k << 1; sonr := sonl + 1; 26 build(sonl, ll, mid); build(sonr, mid+1, rr); 27 sum := tree[sonl].sum + tree[sonr].sum; 28 if ((tree[sonr].sur)>(tree[sonl].sur+tree[sonr].sum)) then sur := tree[sonr].sur 29 else sur := tree[sonl].sur+tree[sonr].sum; 30 if ((tree[sonl].sul)>(tree[sonl].sum+tree[sonr].sul)) then sul := tree[sonl].sul 31 else sul := tree[sonl].sum+tree[sonr].sul; 32 if ((tree[sonl].max)>(tree[sonr].max)) then max := tree[sonl].max 33 else max := tree[sonr].max; 34 if ((tree[sonl].sur+tree[sonr].sul)>(max)) then max := tree[sonl].sur+tree[sonr].sul; 35 end; 36 end; 37 38 procedure init; 39 var 40 i: longint; 41 begin 42 readln(n); 43 for i := 1 to n do read(a[i]); readln; 44 fillchar(tree, sizeof(tree[0]), 0); 45 build(1, 1, n); 46 end; 47 48 procedure change(k, xx, num: longint); 49 var 50 tmp: longint; 51 begin 52 with tree[k] do begin 53 if (l=r) then begin 54 max := num; sum := num; sur := num; sul := num; 55 exit; 56 end 57 else if xx<=mid then change(sonl, xx, num) 58 else if xx>mid then change(sonr, xx, num); 59 sum := tree[sonl].sum + tree[sonr].sum; 60 if ((tree[sonr].sur)>(tree[sonl].sur+tree[sonr].sum)) then sur := tree[sonr].sur 61 else sur := tree[sonl].sur+tree[sonr].sum; 62 if ((tree[sonl].sul)>(tree[sonl].sum+tree[sonr].sul)) then sul := tree[sonl].sul 63 else sul := tree[sonl].sum+tree[sonr].sul; 64 if ((tree[sonl].max)>(tree[sonr].max)) then max := tree[sonl].max 65 else max := tree[sonr].max; 66 if ((tree[sonl].sur+tree[sonr].sul)>(max)) then max := tree[sonl].sur+tree[sonr].sul; 67 end; 68 end; 69 70 function askr(k, xx, yy: longint): longint; 71 var 72 tmp: longint; 73 begin 74 while (xx>tree[k].mid)and(tree[k].sonr<>0) do k := tree[k].sonr; 75 with tree[k] do begin 76 if (l=xx)and(r=yy) then exit(sur); 77 tmp := tree[sonr].sur; 78 askr := tree[sonr].sum + askr(sonl, xx, mid); 79 if tmp>askr then askr := tmp; 80 end; 81 end; 82 83 function askl(k, xx, yy: longint): longint; 84 var 85 tmp: longint; 86 begin 87 while (yy<=tree[k].mid)and(tree[k].sonl<>0) do k := tree[k].sonl; 88 with tree[k] do begin 89 if (l=xx)and(r=yy) then exit(sul); 90 tmp := tree[sonl].sul; 91 askl := tree[sonl].sum + askl(sonr, mid+1, yy); 92 if tmp>askl then askl := tmp; 93 end; 94 end; 95 96 function query(k, xx, yy: longint): longint; 97 var 98 tmp: longint; 99 begin 100 //query := -maxlongint; 101 with tree[k] do begin 102 if (xx<=l)and(r<=yy) then exit(max); 103 if yy<=mid then query := query(sonl, xx, yy) 104 else if xx>mid then query := query(sonr, xx, yy) 105 else begin 106 query := query(sonl, xx, mid); 107 tmp := query(sonr, mid+1, yy); 108 if tmp>query then query := tmp; 109 tmp := askr(sonl, xx, mid) + askl(sonr, mid+1, yy); 110 if tmp>query then query := tmp; 111 end; 112 end; 113 end; 114 115 procedure main; 116 var 117 i, key: longint; 118 begin 119 readln(m); 120 for i := 1 to m do begin 121 readln(key, x, y); 122 if key=0 then change(1, x, y) 123 else writeln(query(1, x, y)); 124 end; 125 end; 126 127 begin 128 assign(input,inf); reset(input); 129 init; 130 main; 131 end.
Spoj 2713 gss4
题意:给出n个数,有两个操作,0 x y ,表示[x,y]中每个数开放向下去整,1 x y,表示求区间[x, y]的和
解:写了两种线段树,都tle了,蛋疼死,上网看了一下其他做法,有一个是暴力更新区间,不过用并差集维护,线段树组求和。我自己也跟风写了这个,疼~~~
1 const 2 maxn=100011; 3 inf='1.txt'; 4 var 5 a, tree: array[0..maxn]of qword; 6 fath: array[0..maxn]of longint; 7 n, m: longint; 8 9 procedure add(x: longint; num: int64); 10 begin 11 while x<=n do begin 12 tree[x] := tree[x] + num; 13 x := x + (x and (-x)); 14 end; 15 end; 16 17 function query(x: longint): qword; 18 begin 19 query := 0; 20 while x>0 do begin 21 query := query + tree[x]; 22 x := x - (x and (-x)); 23 end; 24 end; 25 26 function getfather(x: longint): longint; 27 begin 28 if fath[x]=x then exit(x); 29 fath[x] := getfather(fath[x]); 30 exit(fath[x]); 31 end; 32 33 procedure change(x, y: longint); 34 var 35 i: longint; 36 begin 37 i := getfather(x); 38 while (i<=y)and(i<>0) do begin 39 if a[i]<>1 then begin 40 add(i, -a[i]); 41 a[i] := trunc(sqrt(a[i])); 42 add(i, a[i]); 43 if a[i]=1 then fath[i] := fath[i+1]; 44 end; 45 i := getfather(i+1); 46 end; 47 end; 48 49 procedure init; 50 var 51 i: longint; 52 begin 53 readln(n); 54 fillchar(tree, sizeof(tree), 0); 55 for i := 1 to n do begin 56 read(a[i]); add(i, a[i]); 57 fath[i] := i; 58 end; 59 readln; 60 end; 61 62 procedure main; 63 var 64 i, x, y, key, tmp: longint; 65 begin 66 readln(m); 67 for i := 1 to m do begin 68 readln(key, x, y); 69 if x>y then begin 70 tmp := x; x := y; y := tmp; 71 end; 72 if key=0 then change(x, y) 73 else writeln(query(y)-query(x-1)); 74 end; 75 end; 76 77 var test: longint; 78 79 begin 80 assign(input,inf); reset(input); 81 test := 0; 82 while not seekeof do begin 83 inc(test); 84 writeln('Case #',test,':'); 85 init; 86 main; 87 writeln; 88 end; 89 end.
Spoj 2916 gss5
呼~~,说点闲话,我又回来了,闭关了一个星期后(其实一点收获也没有吧喂!),我终于又回来切题了,我重接着上次的思路去做gss5(居然还接得上),这次的格式我就乱一点了,这次是给出n个数,给出区间左右端点的取值范围,然后求最大值区间,本质是恶心到死的分类讨论,我真是弱死了,切了一个中午,其实我本来的区间划分没什么大问题的,但是最大的问题就是考虑一个区间的值是否为0的时候取舍问题,我写的函数是至少取一个的,那么写的就超级麻烦了,所以最后写了一大堆if,然后子程序也写了4个,超丑,希望日后有空回来写下,对比下,看看自己的进步好了。
1 const 2 maxn=100111; 3 inf='1.txt'; 4 type 5 type_node=record 6 sonl, sonr, l, r, mid, sul, sur, sum, max: longint; 7 end; 8 var 9 tree: array[0..maxn]of type_node; 10 a: array[0..maxn]of longint; 11 i, test, n, m: longint; 12 tmpl, tmpr, tmpm: longint; 13 14 procedure build(k, ll, rr: longint); 15 begin 16 with tree[k] do begin 17 l := ll; r := rr; mid := (l+r)>>1; 18 if l=r then begin 19 sul := a[l]; sur := a[l]; sum := a[l]; max := a[l]; 20 sonl := 0; sonr := 0; 21 exit; 22 end; 23 sonl := k << 1; sonr := sonl + 1; 24 build(sonl, ll, mid); build(sonr, mid+1, rr); 25 sum := tree[sonl].sum + tree[sonr].sum; 26 if ((tree[sonl].sul)>(tree[sonl].sum+tree[sonr].sul)) then sul := tree[sonl].sul 27 else sul := tree[sonl].sum+tree[sonr].sul; 28 if ((tree[sonr].sur)>(tree[sonr].sum+tree[sonl].sur)) then sur := tree[sonr].sur 29 else sur := tree[sonr].sum+tree[sonl].sur; 30 max := sul; 31 if sur>max then max := sur; 32 if tree[sonl].max > max then max := tree[sonl].max; 33 if tree[sonr].max > max then max := tree[sonr].max; 34 if (tree[sonl].sur+tree[sonr].sul>max) then max := tree[sonl].sur+tree[sonr].sul; 35 end; 36 end; 37 38 function query(k, ll, rr: longint): longint; 39 begin 40 if ll>rr then exit(0); 41 with tree[k] do begin 42 if (ll<=l)and(r<=rr) then exit(sum); 43 if ll>mid then query := query(sonr, ll, rr) 44 else if rr<=mid then query := query(sonl, ll, rr) 45 else query := query(sonl, ll, mid) + query(sonr, mid+1, rr); 46 end; 47 end; 48 49 function askl(k, ll, rr: longint): longint; 50 var 51 tmp: longint; 52 begin 53 if ll>rr then exit(0); 54 with tree[k] do begin 55 if (ll<=l)and(r<=rr) then exit(sul); 56 if ll>mid then askl := askl(sonr, ll, rr) 57 else if rr<=mid then askl := askl(sonl, ll, rr) 58 else begin 59 askl := askl(sonl, ll, mid); 60 tmp := query(sonl, ll, mid) + askl(sonr, mid+1, rr); 61 if tmp>askl then askl := tmp; 62 end; 63 end; 64 end; 65 66 function askr(k, ll, rr: longint): longint; 67 var 68 tmp: longint; 69 begin 70 if ll>rr then exit(0); 71 with tree[k] do begin 72 if (ll<=l)and(r<=rr) then exit(sur); 73 if ll>mid then askr := askr(sonr, ll, rr) 74 else if rr<=mid then askr := askr(sonl, ll, rr) 75 else begin 76 askr := askr(sonr, mid+1, rr); 77 tmp := askr(sonl, ll, mid) + query(sonr, mid+1, rr); 78 if tmp>askr then askr := tmp; 79 end; 80 end; 81 end; 82 83 function hora(a, b: longint): longint; 84 begin if a>b then exit(a) else exit(b); end; 85 86 function _max(k, ll, rr: longint): longint; 87 begin 88 if ll>rr then exit(0); 89 with tree[k] do begin 90 if (ll<=l)and(r<=rr) then exit(max); 91 if mid<ll then _max := _max(sonr, ll, rr) 92 else if mid>=rr then _max := _max(sonl, ll, rr) 93 else begin 94 _max := _max(sonl, ll, mid); 95 tmpm := _max(sonr, mid+1, rr); 96 if tmpm>_max then _max := tmpm; 97 tmpm := askr(sonl, ll, mid) + askl(sonr, mid+1, rr); 98 if tmpm>_max then _max := tmpm; 99 end; 100 end; 101 end; 102 103 procedure init; 104 var 105 i: longint; 106 begin 107 read(n); for i := 1 to n do read(a[i]); readln; 108 build(1, 1, n); 109 end; 110 111 procedure main; 112 var 113 i, x1, x2, y1, y2, ans, tmp, ttt: longint; 114 begin 115 readln(m); 116 for i := 1 to m do begin 117 readln(x1, y1, x2, y2); 118 if y1<=x2 then begin 119 ans := query(1, y1, x2); 120 tmp := askr(1, x1, y1-1); if tmp>0 then ans := ans + tmp; 121 tmp := askl(1, x2+1, y2); if tmp>0 then ans := ans + tmp; 122 end 123 else begin 124 ans := _max(1, x2, y1); 125 if x1<x2 then begin 126 tmp := askr(1, x1, x2); 127 ttt := askl(1, x2+1, y1); if ttt>0 then tmp := ttt + tmp; 128 if tmp>ans then ans := tmp; 129 end; 130 if y1<y2 then begin 131 tmp := askl(1, y1, y2); 132 ttt := askr(1, x2, y1-1); if ttt>0 then tmp := ttt + tmp; 133 if tmp>ans then ans := tmp; 134 end; 135 if (x1<x2)and(y1<y2) then begin 136 tmp := query(1, x2, y1); 137 ttt := askr(1, x1, x2-1); if ttt>0 then tmp := ttt + tmp; 138 ttt := askl(1, y1+1, y2); if ttt>0 then tmp := ttt + tmp; 139 if tmp>ans then ans := tmp; 140 end; 141 end; 142 writeln(ans); 143 end; 144 end; 145 146 begin 147 assign(input,inf);reset(input); 148 fillchar(tree, sizeof(tree[0]), 0); 149 readln(test); 150 for i := 1 to test do begin 151 init; 152 main; 153 end; 154 end.
Spoj 4487
Splay裸题,splay比线段树强大在插入删除,静态指针不能释放内存很纠结,而且多次调用函数也让我胆颤心惊,不过还是过了。
1 const 2 oo=maxlongint >> 2; 3 maxn=200011; 4 null=-1; 5 inf='1.txt'; 6 type 7 node=record 8 size, left, right, num, father: longint; 9 maxl, maxr, sum, opt: longint; 10 end; 11 var 12 tree: array[-1..maxn]of node; 13 root, n, q, tot: longint; 14 function max(a, b: longint): longint; 15 begin if a>b then exit(a) else exit(b); end; 16 procedure updata(x: longint); 17 var 18 tmp, tt: longint; 19 begin 20 with tree[x] do begin 21 sum := tree[left].sum + num + tree[right].sum; 22 size := tree[left].size + 1 + tree[right].size; 23 //maxl 24 //tmp := tree[left].maxl; if tmp>maxl then maxl := tmp; 25 maxl := tree[left].maxl; 26 tmp := tree[right].maxl; if tmp<0 then tmp := 0; 27 tmp := tree[left].sum + num + tmp; 28 if tmp>maxl then maxl := tmp; 29 //maxr 30 //tmp := tree[right].maxr; if tmp>maxr then maxr := tmp; 31 maxr := tree[right].maxr; 32 tmp := tree[left].maxr; if tmp<0 then tmp := 0; 33 tmp := tmp + num + tree[right].sum; 34 if tmp>maxr then maxr := tmp; 35 //opt 36 //if maxl > opt then opt := maxl; 37 opt := maxl; 38 if maxr > opt then opt := maxr; 39 if tree[left].opt>opt then opt := tree[left].opt; 40 if tree[right].opt>opt then opt := tree[right].opt; 41 //tmp := tree[left].maxr + num + tree[right].maxl;!! 42 tt := tree[left].maxr; if tt<0 then tt := 0; 43 tmp := num + tt; 44 tt := tree[right].maxl; if tt<0 then tt := 0; 45 tmp := tmp + tt; 46 if tmp>opt then opt := tmp; 47 {maxl:=max(tree[left].maxl,tree[left].sum+num+max(0,tree[right].maxl)); 48 maxr:=max(tree[right].maxr,tree[right].sum+num+max(0,tree[left].maxr)); 49 opt:=max(maxl,maxr); 50 opt:=max(opt,max(tree[left].opt,tree[right].opt)); 51 opt:=max(opt,max(0,tree[left].maxr)+num+max(0,tree[right].maxl));} 52 end; 53 end; 54 55 procedure zig(x: longint); 56 var 57 y, p: longint; 58 begin 59 with tree[x] do begin 60 y := father; if y=root then root := x; 61 tree[y].left := right; 62 if right<>null then tree[right].father := y; 63 p := tree[y].father; 64 father := p; 65 if p<>null then begin 66 if tree[p].left=y then tree[p].left := x 67 else tree[p].right := x; 68 end; 69 right := y; 70 tree[y].father := x; 71 end; 72 updata(y); 73 //updata(x); yihouhuigengxin 74 end; 75 76 procedure zag(x: longint); 77 var 78 y, z: longint; 79 begin 80 with tree[x] do begin 81 y := father; if y=root then root := x; 82 tree[y].right := left; 83 if left<>null then tree[left].father := y; 84 z := tree[y].father; 85 father := z; 86 if z<>null then begin 87 if tree[z].left=y then tree[z].left := x 88 else tree[z].right := x; 89 end; 90 left := y; 91 tree[y].father := x; 92 end; 93 updata(y); 94 end; 95 96 97 function build(l, r: longint): longint; 98 var 99 x: longint; 100 begin 101 x := (l+r)>>1; build := x; 102 with tree[x] do begin 103 if l<x then begin 104 left := build(l, x-1); 105 tree[left].father := x; 106 end else left := null; 107 if x<r then begin 108 right := build(x+1, r); 109 tree[right].father := x; 110 end else right := null; 111 end; 112 updata(x); 113 end; 114 115 function find(x: longint): longint; 116 var 117 i: longint; 118 begin 119 i := root; 120 while true do with tree[i] do begin 121 if tree[left].size+1=x then exit(i); 122 if tree[left].size+1>x then i := left 123 else begin 124 x := x-tree[left].size-1; 125 i := right; 126 end; 127 end; 128 end; 129 130 procedure splay(x, goal: longint); 131 var 132 y, z, u, v: longint; 133 begin 134 while tree[x].father<>goal do with tree[x] do begin 135 y := father; if tree[y].left=x then u := 0 else u := 1; 136 z := tree[y].father; 137 if z=goal then begin 138 if u=0 then zig(x) else zag(x); 139 continue; 140 end; 141 if tree[z].left=y then v := 0 else v := 1; 142 if (u xor v = 0) then begin 143 if u=0 then begin 144 zig(y); zig(x); 145 end 146 else begin 147 zag(y); zag(x); 148 end; 149 end 150 else begin 151 if u=0 then zig(x) else zag(x); 152 if v=0 then zig(x) else zag(x); 153 end; 154 end; 155 updata(x); 156 end; 157 158 procedure ins(x, number: longint); 159 var 160 l, r, y: longint; 161 begin 162 l := find(x-1); splay(l, null); 163 r := find(x); splay(r, root); 164 r := tree[root].right; 165 inc(tot); 166 with tree[tot] do begin 167 num := number; 168 left := null; right := null; 169 updata(tot); 170 //new(tot); 171 end; 172 tree[r].left := tot; 173 tree[tot].father := r; 174 updata(r); 175 updata(root); 176 end; 177 178 procedure del(x: longint); 179 var 180 l, r, y: longint; 181 begin 182 l := find(x-1); splay(l, null); 183 r := find(x+1); splay(r, root); 184 r := tree[root].right; 185 186 tree[r].left := null; 187 updata(r); 188 updata(root); 189 end; 190 191 procedure cha(x, number: longint); 192 var 193 p, l, r, y: longint; 194 begin 195 l := find(x-1); splay(l, null); 196 r := find(x+1); splay(r, root); 197 r := tree[root].right; 198 199 p := tree[r].left; 200 tree[p].num := number; //new(p); 201 updata(p); 202 updata(r); 203 updata(root); 204 end; 205 206 function query(x, y: longint): longint; 207 var 208 l, r, p: longint; 209 begin 210 l := find(x-1); 211 splay(l, null); 212 r := find(y+1); splay(r, root); 213 r := tree[root].right; 214 p := tree[r].left; 215 query := tree[p].opt; 216 end; 217 218 procedure init; 219 var 220 i: longint; 221 begin 222 readln(n); 223 tot := n+1; 224 with tree[0] do begin 225 opt := -oo; maxl := -oo; maxr := -oo; 226 end; 227 with tree[tot] do begin 228 opt := -oo; maxl := -oo; maxr := -oo; 229 end; 230 with tree[null] do begin 231 opt := -oo; maxl := -oo; maxr := -oo; sum := 0; 232 end; 233 for i := 1 to n do with tree[i] do read(num); readln; 234 readln(q); 235 root := build(0, tot); 236 tree[root].father := null; 237 end; 238 239 procedure print(x: longint); 240 var 241 head, tail, i, time, s: longint; 242 q: array[1..100]of longint; 243 begin 244 head := 0; tail := 1; 245 q[tail] := x; 246 i := 32; 247 s := 1; time := 0; 248 while head<>tail do begin 249 inc(head); 250 inc(time); 251 with tree[q[head]] do begin 252 write(q[head]: i); 253 if left<>null then begin 254 inc(tail); 255 q[tail] := left; 256 end; 257 if right<>null then begin 258 inc(tail); 259 q[tail] := right; 260 end; 261 end; 262 if time=s then begin 263 writeln; s := s << 1; i := i >> 1; 264 end; 265 end; 266 end; 267 268 procedure main; 269 var 270 i, x, y, number: longint; 271 c: char; 272 begin 273 for i := 1 to q do begin 274 read(c); 275 case c of 276 'I': begin 277 readln(x, number); inc(x); 278 ins(x, number); 279 end; 280 'D': begin 281 readln(x); inc(x); 282 del(x); 283 end; 284 'R': begin 285 readln(x, number); inc(x); 286 cha(x, number); 287 end; 288 'Q': begin 289 readln(x, y); inc(x); inc(y); 290 writeln(query(x, y)); 291 end; 292 end; 293 //print(root); 294 end; 295 end; 296 297 begin 298 assign(input,inf); reset(input); 299 init; 300 main; 301 end.
Spoj 6779
说点其他,gss到这里也就差不多了,不知道为什么,gss2特别不想切,所以还是等到暑假吧。为了爆掉95什么的,虽然这样说,可是好颓废,嗯,努力吧。
这题神牛表示是树链剖分裸体,于是去了解了一下,之前在黄天神牛的blog里看过,表示眼睛闪闪ym啊, 现在自己也去了解做了一下,具体做法是把一棵树的边分为轻重边,由于性质,一条路径上的轻边重边的数量不会超过logn(具体见国家队2009论文)。然后把连续的重边add进线段树,其他单独add,然后询问路径opt,改值做成线段树询问就行了,不用求lca,慢慢抬上去直到两个端点位于同一条重链上。具体的还是见代码吧,回来再补充。
1 const 2 maxn=101111; 3 def=maxlongint; 4 inf='1.txt'; 5 type 6 type_tree=record 7 flag, sum, opt, maxl, maxr, size, 8 sonl, sonr, l, r, mid: longint; 9 end; 10 type_edge=record 11 dest, next: longint; 12 end; 13 var 14 tree: array[0..maxn*4]of type_tree; 15 edge: array[0..maxn*2]of type_edge; 16 size, w, fa, dep, maxson, a, num, top, vect: array[0..maxn]of longint; 17 n, q, tot, len: longint; 18 19 function max(a, b: longint): longint; 20 begin if a>b then exit(a) else exit(b); end; 21 22 procedure updata(var c, a, b: type_tree); 23 var 24 tmp: longint; 25 k: type_tree; 26 begin 27 k := c; 28 with k do begin 29 sum := a.sum + b.sum; 30 size := a.size + b.size; 31 maxl := a.maxl; tmp := a.sum + b.maxl; if tmp<0 then tmp := 0; 32 if tmp>maxl then maxl := tmp; 33 maxr := b.maxr; tmp := b.sum + a.maxr; if tmp<0 then tmp := 0; 34 if tmp>maxr then maxr := tmp; 35 opt := a.opt; if maxl>maxr then tmp := maxl else tmp:= maxr; 36 if tmp>opt then opt := tmp; 37 if b.opt > opt then opt := b.opt; 38 if (a.maxr + b.maxl > opt ) then opt := a.maxr + b.maxl; 39 end; 40 c := k; 41 end; 42 43 procedure dfs_1(x: longint); 44 var 45 i: longint; 46 tmp: longint; 47 begin 48 i := vect[x]; 49 tmp := 0; 50 while i<>0 do 51 with edge[i] do begin 52 if dest <> fa[x] then begin 53 fa[dest] := x; 54 dfs_1(dest); 55 inc(size[x], size[dest]); 56 if size[dest] > size[tmp] then tmp := dest; 57 end; 58 i := next; 59 end; 60 if size[x] = 0 then size[x] := 1; 61 if tmp <> 0 then maxson[x] := tmp; 62 end; 63 64 procedure dfs_2(x, head, depth: longint); 65 var 66 i: longint; 67 begin 68 top[x] := head; dep[x] := depth; 69 inc(len); a[len] := w[x]; num[x] := len; 70 if maxson[x] <> 0 then dfs_2(maxson[x], head, depth + 1); 71 i := vect[x]; 72 while i<>0 do 73 with edge[i] do begin 74 if (dest <> fa[x])and(dest<>maxson[x]) then begin 75 dfs_2(dest, dest, depth + 1); 76 end; 77 i := next; 78 end; 79 end; 80 81 procedure build(k, left, right: longint); 82 begin 83 with tree[k] do begin 84 flag := def; 85 l := left; r := right; mid := (l+r)>>1; 86 if (l=r) then begin 87 size := 1; opt := a[l]; sum := a[l]; maxl := a[l]; maxr := a[l]; 88 exit; 89 end; 90 sonl := k << 1; sonr := sonl + 1; 91 build(sonl, left, mid); build(sonr, mid + 1, right); 92 updata(tree[k], tree[sonl], tree[sonr]); 93 end; 94 end; 95 96 procedure init; 97 var 98 i, x, y: longint; 99 begin 100 readln(n); 101 for i := 1 to n do read(w[i]); readln; 102 fillchar(vect, sizeof(vect), 0); tot := 0; 103 for i := 1 to n-1 do begin 104 readln(x, y); 105 inc(tot); 106 with edge[tot] do begin 107 dest := y; 108 next := vect[x]; 109 vect[x] := tot; 110 end; 111 inc(tot); 112 with edge[tot] do begin 113 dest := x; 114 next := vect[y]; 115 vect[y] := tot; 116 end; 117 end; 118 fillchar(fa, sizeof(fa), 0); 119 fillchar(size, sizeof(size), 0); 120 fillchar(maxson, sizeof(maxson), 0); 121 dfs_1(1); 122 len := 0; 123 dfs_2(1, 1, 1); 124 //len := 0; 125 build(1, 1, n); 126 end; 127 128 procedure renew(k, cnum: longint); 129 begin 130 with tree[k] do begin 131 sum := size*cnum; 132 if cnum>0 then opt := cnum*size else opt := cnum; 133 maxl := opt; maxr := opt; 134 flag := cnum; 135 end; 136 end; 137 138 procedure clear(k: longint); 139 begin 140 with tree[k] do begin 141 if (l<>r)and(flag<>def) then begin 142 renew(sonl, flag); 143 renew(sonr, flag); 144 flag := def; 145 end; 146 end; 147 end; 148 149 procedure cover(k, left, right, cnum: longint); 150 begin 151 with tree[k] do begin 152 if (left<=l)and(r<=right) then begin 153 renew(k, cnum); 154 exit; 155 end; 156 clear(k); 157 if right<=mid then cover(sonl, left, right, cnum) 158 else if left>mid then cover(sonr, left, right, cnum) 159 else begin 160 cover(sonl, left, mid, cnum); 161 cover(sonr, mid+1, right, cnum); 162 end; 163 updata(tree[k], tree[sonl], tree[sonr]); 164 end; 165 end; 166 167 procedure change(x, y, cnum: longint); 168 var 169 k: longint; 170 f1, f2: longint; 171 begin 172 f1 := top[x]; f2 := top[y]; 173 while f1<>f2 do begin 174 if dep[f1] >= dep[f2] then begin 175 cover(1, num[f1], num[x], cnum); 176 x := fa[f1]; f1 := top[x]; 177 end; 178 if f1=f2 then break; 179 if dep[f2] >= dep[f1] then begin 180 cover(1, num[f2], num[y], cnum); 181 y := fa[f2]; f2 := top[y]; 182 end; 183 end; 184 if dep[x] > dep[y] then begin 185 k := x; x := y; y := k; 186 end; 187 cover(1, num[x], num[y], cnum); 188 end; 189 190 function ask(k, left, right: longint): type_tree; 191 var 192 u, v: type_tree; 193 begin 194 with tree[k] do begin 195 if (left <= l)and(r <= right) then exit(tree[k]); 196 clear(k); 197 if right <= mid then ask := ask(sonl, left, right) 198 else if left > mid then ask := ask(sonr, left, right) 199 else begin 200 u := ask(sonl, left, mid); 201 v := ask(sonr, mid+1, right); 202 updata(ask, u, v); 203 end; 204 end; 205 end; 206 207 function query(x, y: longint): type_tree; 208 var 209 ans1, ans2, tmp: type_tree; 210 f1, f2: longint; 211 begin 212 fillchar(ans1, sizeof(ans1), 0); 213 fillchar(ans2, sizeof(ans2), 0); 214 f1 := top[x]; f2 := top[y]; 215 while f1<>f2 do begin 216 if dep[f1] >= dep[f2] then begin 217 tmp := ask(1, num[f1], num[x]); 218 updata(ans1, tmp, ans1); 219 x := fa[f1]; f1 := top[x]; 220 end; 221 if f1=f2 then break; 222 if dep[f2] >= dep[f1] then begin 223 tmp := ask(1, num[f2], num[y]); 224 updata(ans2, tmp, ans2); 225 y := fa[f2]; f2 := top[y]; 226 end; 227 end; 228 if dep[x]>dep[y] then begin 229 tmp := ask(1, num[y], num[x]); 230 updata(ans1, tmp, ans1); 231 end 232 else begin 233 tmp := ask(1, num[x], num[y]); 234 updata(ans2, tmp, ans2); 235 end; 236 f1 := ans1.maxl; ans1.maxl := ans1.maxr; ans1.maxr := f1; 237 updata(query, ans1, ans2); 238 end; 239 240 procedure main; 241 var 242 i, x, y, z, c: longint; 243 tmp: type_tree; 244 begin 245 readln(q); 246 for i := 1 to q do begin 247 read(c); 248 if c = 1 then begin 249 readln(x, y); 250 writeln(query(x, y).opt); 251 end 252 else begin 253 readln(x, y, z); 254 change(x, y, z); 255 end; 256 end; 257 end; 258 259 begin 260 assign(input, inf); reset(input); 261 init; 262 main; 263 end.
f