spoj,gss系列

Spoj 1034 gss 1

给出n个数,然后q组询问,每组询问x,y,表示求区间[x, y]内的最大连续和是多少

解:线段树,写得很挫,复杂度高死了,有空收集一些高效程序来研究

View Code
  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老是开开关关的..

View Code
  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了,蛋疼死,上网看了一下其他做法,有一个是暴力更新区间,不过用并差集维护,线段树组求和。我自己也跟风写了这个,疼~~~

 

View Code
 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个,超丑,希望日后有空回来写下,对比下,看看自己的进步好了。

 

View Code
  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比线段树强大在插入删除,静态指针不能释放内存很纠结,而且多次调用函数也让我胆颤心惊,不过还是过了。

View Code
  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,慢慢抬上去直到两个端点位于同一条重链上。具体的还是见代码吧,回来再补充。

View Code
  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

 

 

 

 

 

 

posted @ 2012-05-09 17:51  F.D.His.D  阅读(655)  评论(0编辑  收藏  举报