比赛 20140425 评测结果 AWWWWWWW
题目名称 大话西游 最终得分 12
用户昵称 隨風巽 运行时间 0.553 s
代码语言 C++ 内存使用 10.23 MiB
提交时间 2014-04-25 11:53:41
显示代码纯文本
#include<iostream>
#include<cstdio>
#include<vector>
#include<cstdlib>
#include<algorithm>
#define INF 200000000
using namespace std;
const int MAXN=100000+10;
struct Edge{int u,v;}edges[MAXN];
int N,Q,total=1,imp[MAXN],temp[MAXN],map[MAXN],x[MAXN],y[MAXN],I,J,P,W;
//map[i]表示原树中的结点i对应的编号
int mino[MAXN*8],maxo[MAXN*8],ansmin,ansmax;
vector<int>g[MAXN];
int min(int a,int b){return a<b?a:b;}
int max(int a,int b){return a>b?a:b;}
void DFS(int v,int par)
{
	int n=g[v].size(),i,u;
	map[v]=total++;
	x[map[v]]=total-1;
	for(i=0;i<n;i++)
	{
		u=g[v][i];
		if(u!=par)DFS(u,v);
	}
	y[map[v]]=total-1;
}
void MAINTAIN(int v,int l,int r)
{
	if(r-l>0)
	{
		int lc=(v<<1),rc=(v<<1|1);
		mino[v]=min(mino[lc],mino[rc]);
		maxo[v]=max(maxo[lc],maxo[rc]);
	}
	else mino[v]=maxo[v]=imp[l];
}
void BUILD(int v,int l,int r)
{
	if(r-l>0)
	{
		int mid=(l+r)>>1;
		BUILD(v<<1,l,mid);
		BUILD(v<<1|1,mid+1,r);
	}
	MAINTAIN(v,l,r);
}
void SET(int v,int l,int r)
{
    if(l==r)imp[P]=W;
	else
	{
		int mid=(l+r)>>1;
		if(P<=mid)SET(v<<1,l,mid);
	    else SET(v<<1|1,mid+1,r);
	}
	MAINTAIN(v,l,r);
}
void QUERY(int v,int l,int r)
{
	if(I<=l&&r<=J)
	{	
		ansmin=min(ansmin,mino[v]);
		ansmax=max(ansmax,maxo[v]);
	}
	else 
	{
		int mid=(l+r)>>1;
		if(I<=mid)QUERY(v<<1,l,mid);
		if(J>=mid+1)QUERY(v<<1|1,mid+1,r);
	}
}
int main()
{
	freopen("westward.in","r",stdin);
	freopen("westward.out","w",stdout);
	scanf("%d%d",&N,&Q);
	int i,e,u,v,t,min1,min2,max1,max2;
	char s[10];
	for(i=1;i<=N;i++)
		scanf("%d",&temp[i]);
	for(i=1;i<=N-1;i++)
	{
		scanf("%d%d",&u,&v);
		g[u].push_back(v);g[v].push_back(u);
		edges[i]=(Edge){u,v};
	}
	DFS(1,-1);
	for(i=1;i<=N;i++)
		imp[map[i]]=temp[i];
	BUILD(1,1,N);
	//for(i=1;i<=N;i++)
	//	cout<<i<<':'<<map[i]<<'('<<x[map[i]]<<','<<y[map[i]]<<')'<<endl;
	for(i=1;i<=Q;i++)
	{	
		scanf("\n%s",&s);
		if(s[0]=='Q')
		{	
			scanf("%d",&e);//u>v
			u=map[edges[e].u];v=map[edges[e].v];
			if(u<v){t=u;u=v;v=t;}
			
			ansmin=INF;ansmax=-INF;
			I=x[u];J=y[u];
			QUERY(1,1,N);
			min1=ansmin;max1=ansmax;
			
			ansmin=INF;ansmax=-INF;
			I=1;J=x[u]-1;
			if(I<=J)QUERY(1,1,N);
			//	cout<<I<<' '<<J<<endl;
			
			I=y[u]+1;J=N;
		    if(I<=J)QUERY(1,1,N);
			min2=ansmin;max2=ansmax;
			//cout<<I<<' '<<J<<endl;
			//cout<<min2<<' '<<max2<<endl;
			cout<<min1*max1+min2*max2<<endl;
		}
		else if(s[0]=='C')
		{	
			scanf("%d%d",&P,&W);
			P=map[P];
			SET(1,1,N);
		}
	}
	return 0;
}