【解题思路】

  直接上树剖套线段树/BIT即可。复杂度o(n+qlog22n)(线段树)或o(n+qlog23n)(BIT)。

【参考代码】

  树剖套BIT。(这个树剖好naive啊QAQ)

 #include <algorithm>
#include <cctype>
#include <cstdio>
#define REP(I,start,end) for(int I=(start);I<=(end);I++)
#define PER(I,start,end) for(int I=(start);I>=(end);I--)
#define ClearStack(_stack) while(!_stack.empty()){_stack.pop();}
#define ClearQueue(_queue) while(!_queue.empty()){_queue.pop();}
#define ClearArray(_array,from,to,val) REP(i,from,to){_array[i]=val;}
#define maxint 32767
#define maxlongint 2147483647
#define maxint64 9223372036854775807ll
inline void space()
{
putchar(' ');
}
inline void enter()
{
putchar('\n');
}
inline bool eoln(char ptr)
{
return ptr=='\n';
}
inline bool eof(char ptr)
{
return ptr=='\0';
}
inline int getint()
{
char ch=getchar();
for(;!isdigit(ch)&&ch!='+'&&ch!='-';ch=getchar());
bool impositive=ch=='-';
if(impositive)
ch=getchar();
int result=;
for(;isdigit(ch);ch=getchar())
result=(result<<)+(result<<)+ch-'';
return impositive?-result:result;
}
inline char *getstr()
{
char *result=new char[],*ptr=result,ch=getchar();
for(;isspace(ch)||eoln(ch)||eof(ch);ch=getchar());
for(;!isspace(ch)&&!eoln(ch)&&!eof(ch);ch=getchar())
{
*ptr=ch;
ptr++;
}
*ptr='\0';
return result;
}
template<typename integer> inline int write(integer n)
{
integer now=n;
bool impositive=now<;
if(impositive)
{
putchar('-');
now=-now;
}
char sav[];
sav[]=now%+'';
int result=;
for(;now/=;sav[result++]=now%+'');
PER(i,result-,)
putchar(sav[i]);
return result+impositive;
}
template<typename T> inline bool getmax(T &target,T pattern)
{
return pattern>target?target=pattern,true:false;
}
template<typename T> inline bool getmin(T &target,T pattern)
{
return pattern<target?target=pattern,true:false;
}
template<typename T> class BIT
{
private:
int size;
T _nINF,_INF,*sav,*savSum,*savMax,*savMin;
int lowbit(int now)
{
return now&-now;
}
public:
inline void clear(int length,T nINF=-maxlongint,T INF=maxlongint)
{
size=length;
delete []sav;
delete []savSum;
delete []savMax;
delete []savMin;
sav=new T[size+];
savSum=new T[size+];
savMin=new T[size+];
savMax=new T[size+];
_nINF=nINF;
_INF=INF;
ClearArray(sav,,size,);
ClearArray(savSum,,size,);
ClearArray(savMax,,size,_nINF);
ClearArray(savMin,,size,_INF);
}
inline void increase(int point,T delta)
{
sav[point]+=delta;
for(int i=point;i<=size;i+=lowbit(i))
{
savSum[i]+=delta;
savMax[i]=savMin[i]=sav[i];
for(int j=;j<lowbit(i);j<<=)
{
getmax(savMax[i],savMax[i-j]);
getmin(savMin[i],savMin[i-j]);
}
}
}
inline void change(int point,T val)
{
T delta=val-sav[point];
sav[point]=val;
for(int i=point;i<=size;i+=lowbit(i))
{
savSum[i]+=delta;
savMax[i]=savMin[i]=sav[i];
for(int j=;j<lowbit(i);j<<=)
{
getmax(savMax[i],savMax[i-j]);
getmin(savMin[i],savMin[i-j]);
}
}
}
inline T pre_sum(int length)
{
T result=T();
for(int i=length;i;i-=lowbit(i))
result+=savSum[i];
return result;
}
inline T query_sum(int left,int right)
{
return pre_sum(right)-pre_sum(left-);
}
inline T query_max(int left,int right)
{
T result=sav[right];
for(int l=left,r=right;l<r;)
{
for(r--;r-l>=lowbit(r);r-=lowbit(r))
getmax(result,savMax[r]);
getmax(result,sav[r]);
}
return result;
}
inline T query_min(int left,int right)
{
T result=sav[right];
for(int l=left,r=right;l<r;)
{
for(r--;r-l>=lowbit(r);r-=lowbit(r))
getmin(result,savMin[r]);
getmin(result,sav[r]);
}
return result;
}
};
//=============================Header Template===============================
#include <cstring>
#include <vector>
using namespace std;
typedef vector<int> vecint;
BIT<int> bit[];
int depth[],w[],father[],weight[],wfa[],wson[],group[],position[];
vecint lines[];
int DFS(int now)
{
weight[now]=;
for(vecint::iterator i=lines[now].begin();i!=lines[now].end();i++)
{
int p=*i;
if(!weight[p])
{
father[p]=now;
weight[now]+=DFS(p);
}
}
return weight[now];
}
void DFSdep(int now,int deep)
{
if(!now)
return;
depth[now]=deep;
for(vecint::iterator i=lines[now].begin();i!=lines[now].end();i++)
{
int p=*i;
if(p!=father[now]&&p!=wson[now])
DFSdep(p,deep+);
}
DFSdep(wson[now],deep);
}
int main()
{
int n=getint();
memset(lines,,sizeof(lines));
REP(i,,n)
{
int u=getint(),v=getint();
lines[u].push_back(v);
lines[v].push_back(u);
}
REP(i,,n)
w[i]=getint();
memset(weight,,sizeof(weight));
father[]=father[]=;
DFS();
memset(wson,,sizeof(wson));
REP(i,,n)
{
int maxer=;
for(vecint::iterator j=lines[i].begin();j!=lines[i].end();j++)
{
int p=*j;
if(p!=father[i]&&getmax(maxer,weight[p]))
wson[i]=p;
}
}
int cnt=;
DFSdep(,);
REP(i,,n)
if(wson[father[i]]!=i)
{
cnt++;
int place=;
for(int j=i;j;j=wson[j])
{
wfa[j]=i;
group[j]=cnt;
position[j]=++place;
}
bit[cnt].clear(place);
for(int j=i;j;j=wson[j])
bit[cnt].change(position[j],w[j]);
}
int q=getint();
while(q--)
{
char *opt=getstr();
int u=getint(),v=getint();
if(!strcmp(opt,"CHANGE"))
bit[group[u]].change(position[u],v);
if(!strcmp(opt,"QSUM"))
{
int ans=;
for(;depth[u]>depth[v];u=father[wfa[u]])
{
int left=position[u],right=position[wfa[u]];
if(left>right)
swap(left,right);
ans+=bit[group[u]].query_sum(left,right);
}
for(;depth[u]<depth[v];v=father[wfa[v]])
{
int left=position[v],right=position[wfa[v]];
if(left>right)
swap(left,right);
ans+=bit[group[v]].query_sum(left,right);
}
for(;wfa[u]!=wfa[v];u=father[wfa[u]],v=father[wfa[v]])
{
int left=position[u],right=position[wfa[u]];
if(left>right)
swap(left,right);
ans+=bit[group[u]].query_sum(left,right);
left=position[v];right=position[wfa[v]];
if(left>right)
swap(left,right);
ans+=bit[group[v]].query_sum(left,right);
}
int left=position[u],right=position[v];
if(left>right)
swap(left,right);
ans+=bit[group[u]].query_sum(left,right);
write(ans);
enter();
}
if(!strcmp(opt,"QMAX"))
{
int ans=-maxlongint;
for(;depth[u]>depth[v];u=father[wfa[u]])
{
int left=position[u],right=position[wfa[u]];
if(left>right)
swap(left,right);
getmax(ans,bit[group[u]].query_max(left,right));
}
for(;depth[u]<depth[v];v=father[wfa[v]])
{
int left=position[v],right=position[wfa[v]];
if(left>right)
swap(left,right);
getmax(ans,bit[group[v]].query_max(left,right));
}
for(;wfa[u]!=wfa[v];u=father[wfa[u]],v=father[wfa[v]])
{
int left=position[u],right=position[wfa[u]];
if(left>right)
swap(left,right);
getmax(ans,bit[group[u]].query_max(left,right));
left=position[v];right=position[wfa[v]];
if(left>right)
swap(left,right);
getmax(ans,bit[group[v]].query_max(left,right));
}
int left=position[u],right=position[v];
if(left>right)
swap(left,right);
getmax(ans,bit[group[u]].query_max(left,right));
write(ans);
enter();
}
}
return ;
}

bzoj1036题解的更多相关文章

  1. BZOJ1036[ZJOI2008]树的统计Count 题解

    题目大意: 一棵树上有n个节点,编号分别为1到n,每个节点都有一个权值w.有一些操作:1.把结点u的权值改为t:2.询问从点u到点v的路径上的节点的最大权值 3.询问从点u到点v的路径上的节点的权值和 ...

  2. BZOJ1036:[ZJOI2008]树的统计——题解

    http://www.lydsy.com/JudgeOnline/problem.php?id=1036 题目描述 一棵树上有n个节点,编号分别为1到n,每个节点都有一个权值w. 我们将以下面的形式来 ...

  3. 【BZOJ1036】[ZJOI2008]树的统计Count 树链剖分

    [BZOJ1036][ZJOI2008]树的统计Count Description 一棵树上有n个节点,编号分别为1到n,每个节点都有一个权值w.我们将以下面的形式来要求你对这棵树完成一些操作: I. ...

  4. 【bzoj1036】 ZJOI2008—树的统计Count

    http://www.lydsy.com/JudgeOnline/problem.php?id=1036 (题目链接) 题意 动态维护树上两点间最大权值和权值和. Solution 裸树链剖分. 这一 ...

  5. BZOJ1036 [ZJOI2008]树的统计Count 树链剖分

    欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - BZOJ1036 题意概括 一个树,每个节点有一个权值.3种操作. 1:修改某一个节点的权值. 2:询问某两个 ...

  6. 2016 华南师大ACM校赛 SCNUCPC 非官方题解

    我要举报本次校赛出题人的消极出题!!! 官方题解请戳:http://3.scnuacm2015.sinaapp.com/?p=89(其实就是一堆代码没有题解) A. 树链剖分数据结构板题 题目大意:我 ...

  7. noip2016十连测题解

    以下代码为了阅读方便,省去以下头文件: #include <iostream> #include <stdio.h> #include <math.h> #incl ...

  8. BZOJ-2561-最小生成树 题解(最小割)

    2561: 最小生成树(题解) Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 1628  Solved: 786 传送门:http://www.lyd ...

  9. Codeforces Round #353 (Div. 2) ABCDE 题解 python

    Problems     # Name     A Infinite Sequence standard input/output 1 s, 256 MB    x3509 B Restoring P ...

随机推荐

  1. nodejs express的基本用法

    demo /** * Created by ZXW on 2017/11/6. */ var express=require("express"); var server=expr ...

  2. mysql rpm包安装

    MySql5.7 安装文档 1.yum repo 安装 ``` wget http://dev.mysql.com/get/mysql57-community-release-el6-11.noarc ...

  3. linux上文件内容去重的问题uniq/awk 正则表达过滤操作

    .uniq:只会对相邻的行进行判断是否重复,不能全文本进行搜索是否重复,所以往往跟sort结合使用. 例子1: [root@aaa01 ~]# cat a.txt 12 34 56 12 [root@ ...

  4. js实现复制|剪切指定内容到粘贴板--clipboard

    这是著名开源项目 clipboard.js 的 README.md,里面讲解的更加详细,有兴趣的同学可以了解一下.项目地址:https://github.com/zenorocha/clipboard ...

  5. 常见条码类型介绍(Code 39、Code 128、EAN-8、EAN-13、EAN-128、ISSN、TIF、TIF-14、UPC(A)、UPC(E))

    常见条码类型,如下: 1.Code 39 Code 39,又称为"Code 3 of 9",是非零售市场中最常用的格式,用于盘存和跟踪.Code 39码编码规则简单,误码率低.所能 ...

  6. 【TCP】SYN攻击

    TCP握手协议 在TCP/IP协议中,TCP协议提供可靠的连接服务,采用三次握手建立一个连接.第一次握手:建立连接时,客户端发送syn包(syn=j)到服务器,并进入SYN_SEND状态,等待服务器确 ...

  7. composer安装后台模板

    先下载composer的windows安装包 cmd切换到源代码所在目录 https://www.cnblogs.com/wgphp/p/8001434.html 安装过程可以参照这篇文章 一点问题是 ...

  8. Shiro学习(21)授予身份及切换身份

    在一些场景中,比如某个领导因为一些原因不能进行登录网站进行一些操作,他想把他网站上的工作委托给他的秘书,但是他不想把帐号/密码告诉他秘书,只是想把工作委托给他:此时和我们可以使用Shiro的RunAs ...

  9. Android中父View和子view的点击事件的执行过程

    Android中的事件类型分为按键事件和屏幕触摸事件,Touch事件是屏幕触摸事件的基础事件,有必要对它进行深入的了解.  一个最简单的屏幕触摸动作触发了一系列Touch事件:ACTION_DOWN- ...

  10. 序列递推——cf1204E(好题)

    /* 显然用dp[i][j]来表示i个1,j个-1的结果 dp[i][j]由dp[i-1][j]和dp[i][j-1]转移而来 即dp[i][j]对应的所有序列,都可以由dp[i-1][j]在前面加一 ...