BZOJ3531: [Sdoi2014]旅行

3531: [Sdoi2014]旅行

Time Limit: 20 Sec  Memory Limit: 512 MB
Submit: 333  Solved: 197
[Submit][Status]

Description

 S国有N个城市,编号从1到N。城市间用N-1条双向道路连接,满足
从一个城市出发可以到达其它所有城市。每个城市信仰不同的宗教,如飞天面条神教、隐形独角兽教、绝地教都是常见的信仰。为了方便,我们用不同的正整数代表各种宗教,  S国的居民常常旅行。旅行时他们总会走最短路,并且为了避免麻烦,只在信仰和他们相同的城市留宿。当然旅程的终点也是信仰与他相同的城市。S国政府为每个城市标定了不同的旅行评级,旅行者们常会记下途中(包括起点和终点)留宿过的城市的评级总和或最大值。
    在S国的历史上常会发生以下几种事件:
”CC x c”:城市x的居民全体改信了c教;
”CW x w”:城市x的评级调整为w;
”QS x y”:一位旅行者从城市x出发,到城市y,并记下了途中留宿过的城市的评级总和;
”QM x y”:一位旅行者从城市x出发,到城市y,并记下了途中留宿过
的城市的评级最大值。
    由于年代久远,旅行者记下的数字已经遗失了,但记录开始之前每座城市的信仰与评级,还有事件记录本身是完好的。请根据这些信息,还原旅行者记下的数字。    为了方便,我们认为事件之间的间隔足够长,以致在任意一次旅行中,所有城市的评级和信仰保持不变。

Input

    输入的第一行包含整数N,Q依次表示城市数和事件数。
    接下来N行,第i+l行两个整数Wi,Ci依次表示记录开始之前,城市i的
评级和信仰。
    接下来N-1行每行两个整数x,y表示一条双向道路。
    接下来Q行,每行一个操作,格式如上所述。

Output

    对每个QS和QM事件,输出一行,表示旅行者记下的数字。

Sample Input

5 6
3 1
2 3
1 2
3 3
5 1
1 2
1 3
3 4
3 5
QS 1 5
CC 3 1
QS 1 5
CW 3 3
QS 1 5
QM 2 4

Sample Output

8
9
11
3

HINT

 

N,Q < =10^5    , C < =10^5


 数据保证对所有QS和QM事件,起点和终点城市的信仰相同;在任意时

刻,城市的评级总是不大于10^4的正整数,且宗教值不大于C。

 

Source

题解:
Greens的动态开点实在不能再炫酷,真是长见识了!
终于A掉了这道题
做树链剖分让我充分意识到了线段树的强大。。。真是灵活的数据结构
这题的动态开点技巧还需要慢慢品味
代码:
  1 {$M 10000000,0,maxlongint}
  2 const maxn=100000+10;
  3 type node1=record
  4      go,next:longint;
  5      end;
  6      node2=record
  7      l,r,mid,lch,rch,mx:longint;
  8      sum:int64;
  9      end;
 10 
 11 var  e:array[0..2*maxn] of node1;
 12      t:array[0..40*maxn] of node2;
 13      p,fa,s,head,dep,son,top,w,c,rt:array[0..maxn] of longint;
 14      i,n,m,x,y,z,sz,tot,cnt,root:longint;
 15      ans:int64;
 16      ch:char;
 17       procedure swap(var x,y:longint);
 18       var t:longint;
 19       begin
 20         t:=x;x:=y;y:=t;
 21       end;
 22      procedure insert(x,y:longint);
 23       begin
 24         inc(tot);
 25         e[tot].go:=y;e[tot].next:=head[x];head[x]:=tot;
 26       end;
 27      function min(x,y:longint):longint;
 28       begin
 29         if x<y then exit(x) else exit(y);
 30       end;
 31      function max(x,y:longint):longint;
 32       begin
 33         if x>y then exit(x) else exit(y);
 34       end;
 35 procedure dfs1(x:longint);
 36  var i,j,y:longint;
 37  begin
 38    j:=0;s[x]:=1;
 39    i:=head[x];
 40    while i<>0 do
 41     begin
 42      y:=e[i].go;
 43      if dep[y]=0 then
 44        begin
 45          dep[y]:=dep[x]+1;
 46          fa[y]:=x;
 47          dfs1(y);
 48          inc(s[x],s[y]);
 49          if s[y]>s[j] then j:=y;
 50        end;
 51      i:=e[i].next;
 52     end;
 53    son[x]:=j;
 54  end;
 55 procedure dfs2(x,chain:longint);
 56  var i,y:longint;
 57  begin
 58    inc(sz);p[x]:=sz;top[x]:=chain;
 59    if son[x]<>0 then dfs2(son[x],chain);
 60    i:=head[x];
 61    while i<>0 do
 62      begin
 63       y:=e[i].go;
 64       if (y<>son[x]) and (y<>fa[x]) then dfs2(y,y);
 65       i:=e[i].next;
 66      end;
 67  end;
 68 procedure pushup(k:longint);
 69  begin
 70    with t[k] do
 71     begin
 72       mx:=max(t[lch].mx,t[rch].mx);
 73       sum:=t[lch].sum+t[rch].sum;
 74     end;
 75  end;
 76 procedure change(var k:longint;x,y,pos,val:longint);
 77  begin
 78    if k=0 then begin inc(cnt);k:=cnt;end;
 79    with t[k] do
 80     begin
 81      l:=x;r:=y;mid:=(l+r)>>1;
 82      if l=r then begin mx:=val;sum:=val;exit;end;
 83      if pos<=mid then change(lch,l,mid,pos,val)
 84      else change(rch,mid+1,r,pos,val);
 85      pushup(k);
 86     end;
 87  end;
 88 procedure init;
 89  begin
 90    readln(n,m);
 91    for i:=1 to n do readln(w[i],c[i]);
 92    for i:=1 to n-1 do begin readln(x,y);insert(x,y);insert(y,x);end;
 93    dep[1]:=1;
 94    dfs1(1);
 95    dfs2(1,1);
 96    cnt:=0;
 97    for i:=1 to n do change(rt[c[i]],1,n,p[i],w[i]);
 98  end;
 99 function getmx(k,x,y:longint):longint;
100  begin
101    if k=0 then exit(0);
102    with t[k] do
103     begin
104      if (l=x) and (r=y) then exit(mx);
105      if y<=mid then exit(getmx(lch,x,y))
106      else if x>mid then exit(getmx(rch,x,y))
107      else exit(max(getmx(lch,x,mid),getmx(rch,mid+1,y)));
108     end;
109  end;
110 function getsum(k,x,y:longint):int64;
111  begin
112    if k=0 then exit(0);
113    with t[k] do
114     begin
115      if (l=x) and (r=y) then exit(sum);
116      if y<=mid then exit(getsum(lch,x,y))
117      else if x>mid then exit(getsum(rch,x,y))
118      else exit(getsum(lch,x,mid)+getsum(rch,mid+1,y));
119     end;
120  end;
121 procedure solvemx;
122  begin
123    ans:=0;
124    readln(x,y);root:=rt[c[x]];
125    while top[x]<>top[y] do
126      begin
127       if dep[top[x]]<dep[top[y]] then swap(x,y);
128       ans:=max(ans,getmx(root,p[top[x]],p[x]));
129       x:=fa[top[x]];
130      end;
131    if dep[x]>dep[y] then swap(x,y);
132    ans:=max(ans,getmx(root,p[x],p[y]));
133    writeln(ans);
134  end;
135 procedure solvesum;
136  begin
137    ans:=0;
138    readln(x,y);root:=rt[c[x]];
139    while top[x]<>top[y] do
140      begin
141       if dep[top[x]]<dep[top[y]] then swap(x,y);
142       inc(ans,getsum(root,p[top[x]],p[x]));
143       x:=fa[top[x]];
144      end;
145    if dep[x]>dep[y] then swap(x,y);
146    inc(ans,getsum(root,p[x],p[y]));
147    writeln(ans);
148  end;
149 procedure main;
150  begin
151    for i:=1 to m do
152     begin
153      read(ch,ch);
154      case ch of
155      'W':begin
156          readln(x,y);
157          w[x]:=y;
158          change(rt[c[x]],1,n,p[x],y);
159          end;
160      'C':begin
161          readln(x,y);
162          change(rt[c[x]],1,n,p[x],0);
163          c[x]:=y;
164          change(rt[y],1,n,p[x],w[x]);
165          end;
166      'M':solvemx;
167      'S':solvesum;
168     end;
169    end;
170  end;
171 begin
172   assign(input,'input.txt');assign(output,'output.txt');
173   reset(input);rewrite(output);
174   init;
175   main;
176   close(input);close(output);
177 end.    
View Code

 

posted @ 2014-08-10 01:02  ZYF-ZYF  Views(296)  Comments(0Edit  收藏  举报