<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>Spoj on Ruotian&#39;s I/O</title>
    <link>https://ruotian.io/tags/spoj/</link>
    <description>Recent content in Spoj on Ruotian&#39;s I/O</description>
    <image>
      <title>Ruotian&#39;s I/O</title>
      <url>https://ruotian.io/apple-touch-icon.png</url>
      <link>https://ruotian.io/apple-touch-icon.png</link>
    </image>
    <generator>Hugo</generator>
    <language>zh</language>
    <lastBuildDate>Tue, 06 Jan 2015 17:12:35 +0800</lastBuildDate>
    <atom:link href="https://ruotian.io/tags/spoj/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>SPOJ QTREE系列</title>
      <link>https://ruotian.io/2015/01/spoj-qtree/</link>
      <pubDate>Tue, 06 Jan 2015 17:12:35 +0800</pubDate>
      <guid>https://ruotian.io/2015/01/spoj-qtree/</guid>
      <description>&lt;h3 id=&#34;375qtree&#34;&gt;375.QTREE&lt;/h3&gt;
&lt;p&gt;给你一棵n个点$n-1$条边的树，支持修改一条边的边权、查询两点之间路径上的最大边权。&lt;/p&gt;
&lt;p&gt;树链剖分+线段树基础题&lt;/p&gt;
&lt;!-- more --&gt;
&lt;hr&gt;
&lt;p&gt;code:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#include&amp;lt;cstdio&amp;gt;
#include&amp;lt;cstring&amp;gt;
#include&amp;lt;algorithm&amp;gt;
using namespace std;
int n;
int H[10005],X[20005],P[20005],tot, w[20005],E[20005],num[20005];
inline void add(int x,int y,int z,int no){
	P[++tot]=y;X[tot]=H[x];H[x]=tot;E[tot]=z;num[tot]=no;
}
int mx[10005&amp;lt;&amp;lt;2];
int to[10005],tt,siz[10005],son[10005],top[10005],dep[10005],f[10005],tim;
void dfs1(int x,int fa){
	siz[x]=1;son[x]=0;top[x]=0;
	int mx=0;
	for(int i=H[x];i;i=X[i]){
		if(P[i]==fa) continue;
		f[P[i]]=x;
		dep[P[i]]=dep[x]+1;
		w[P[i]]=E[i];
		to[num[i]]=P[i];
		dfs1(P[i],x);
		siz[x]+=siz[P[i]];
		if(siz[P[i]]&amp;gt;mx){
			mx=siz[P[i]];
			son[x]=P[i];
		}
	}
}
void dfs2(int x,int fa){
	if(!top[x]) top[x]=x;
	num[x]=++tim;
	E[tim]=w[x];
	if(son[x])top[son[x]]=top[x],dfs2(son[x],x);
	for(int i=H[x];i;i=X[i]){
		if(P[i]!=son[x]&amp;amp;&amp;amp;P[i]!=fa){
			dfs2(P[i],x);
		}
	}
}
int _c,_l,_r;
void ask(int o,int l,int r){
	if(_l&amp;lt;=l&amp;amp;&amp;amp;r&amp;lt;=_r){
		_c=max(mx[o],_c);
		return ;
	}else{
		int mid=(l+r)&amp;gt;&amp;gt;1;
		if(_l&amp;lt;=mid) ask(o&amp;lt;&amp;lt;1,l,mid);
		if(_r&amp;gt;mid) ask(o&amp;lt;&amp;lt;1|1,mid+1,r);
	}
}
int ask(int l,int r){
	_c=0;
	_l=l,_r=r;
	ask(1,1,n);
	return _c;
}
int Ask(int a,int b){
	int ret=0;
	while(top[a]!=top[b]){
		int x=top[a],y=top[b];
		if(dep[x]&amp;lt;dep[y]) swap(x,y),swap(a,b);
		ret=max(ask(num[x],num[a]),ret);
		a=f[x];
		
	}
	if(a!=b){
		if(dep[a]&amp;gt;dep[b]) swap(a,b);
		ret=max(ret,ask(num[a]+1,num[b]));
	}
	return ret;
}
char s[50];
void change(int o,int l,int r,int p,int k){
	if(l==r){
		mx[o]=k;
	}else{
		int mid=(l+r)&amp;gt;&amp;gt;1;
		if(p&amp;lt;=mid) change(o&amp;lt;&amp;lt;1,l,mid,p,k);
		else change(o&amp;lt;&amp;lt;1|1,mid+1,r,p,k);
		mx[o]=max(mx[o&amp;lt;&amp;lt;1],mx[o&amp;lt;&amp;lt;1|1]);
	}
}
void bd(int o,int l,int r){
	if(l==r){
		mx[o]=E[l];
	}else{
		int mid=(l+r)&amp;gt;&amp;gt;1;
		bd(o&amp;lt;&amp;lt;1,l,mid);
		bd(o&amp;lt;&amp;lt;1|1,mid+1,r);
		mx[o]=max(mx[o&amp;lt;&amp;lt;1],mx[o&amp;lt;&amp;lt;1|1]);
	}
}
int main(){
	scanf(&amp;quot;%d&amp;quot;,&amp;amp;tt);
	while(tt--){
		tim=tot=0;
		memset(H,0,sizeof H);
		scanf(&amp;quot;%d&amp;quot;,&amp;amp;n);
		for(int i=1,a,b,c;i&amp;lt;n;i++){
			scanf(&amp;quot;%d%d%d&amp;quot;,&amp;amp;a,&amp;amp;b,&amp;amp;c);
			add(a,b,c,i);
			add(b,a,c,i);
		}
		dep[1]=1;
		dfs1(1,-1);
		dfs2(1,-1);
		bd(1,1,n);
		int a,b;
		while(scanf(&amp;quot;%s&amp;quot;,s),s[0]!=&#39;D&#39;){
			if(s[0]==&#39;Q&#39;){
				scanf(&amp;quot;%d%d&amp;quot;,&amp;amp;a,&amp;amp;b);
				printf(&amp;quot;%d\n&amp;quot;,Ask(a,b));
			}else{
				scanf(&amp;quot;%d%d&amp;quot;,&amp;amp;a,&amp;amp;b);
				change(1,1,n,num[to[a]],b);
			}
		}
	}
	return 0;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;hr&gt;
&lt;h3 id=&#34;913qtree2&#34;&gt;913.QTREE2&lt;/h3&gt;
&lt;p&gt;一棵树，两个操作。&lt;br&gt;
1.询问a到b的最短路。&lt;br&gt;
2.询问a到b的最短路上第k个点是啥。&lt;br&gt;
倍增或者树链剖分。&lt;/p&gt;</description>
    </item>
    <item>
      <title>SPOJ GSS 系列</title>
      <link>https://ruotian.io/2015/01/spoj-gss/</link>
      <pubDate>Tue, 06 Jan 2015 17:12:20 +0800</pubDate>
      <guid>https://ruotian.io/2015/01/spoj-gss/</guid>
      <description>&lt;p&gt;SPOJ GSS系列是一系列序列维护的问题。 &lt;br&gt;
大部分用线段树，Splay等可以解决。&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id=&#34;1043-gss1&#34;&gt;1043. GSS1&lt;/h3&gt;
&lt;p&gt;题意：给定长度为N的数串，M个询问查询[a,b]的的最大连续子段和。&lt;br&gt;
线段树每个节点维护左端最大连续和，右端最大连续和，中间最大连续和。 &lt;br&gt;
就可以快速合并了。&lt;/p&gt;</description>
    </item>
  </channel>
</rss>
