【解题思路】

  直接上树剖套线段树/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. 纯前端html导出pdf--分页+不分页--html2canvas+jsPDF

    前言 最近在项目中,有一个导出pdf功能,需要纯前端来实现,调研了多种pdf导出方式,最终决定使用html2canvas+jsPDF来实现需求. 本文就简单介绍一下html2canvas+jsPDF导 ...

  2. leetcood学习笔记-28-KMP*

    题目: 第一次提交: class Solution: def strStr(self, haystack: str, needle: str) -> int: if not len(needle ...

  3. bootstrap相关使用

    如果想做成响应式效果,使用栅格系统产生 小于768手机端 : col-xs- 大于768小于992平板 : col-sm- 大于992小于1200 : col-md- 大于1200 : col-lg- ...

  4. 重视项目排期,对dateline 有所敬畏

    项目排期 = 个人任务完成 + 风险预估 + 意外情况 + 项目上下游依赖 个人任务完成 个人任务具体话 不要考虑私人情感,专注工作 风险预估 对可能出现的情况进行考虑 意外情况 对出现的意外情况提前 ...

  5. python 爬取头条视频

    知识点总结 1. 利用webdriver 模拟浏览器访问 from selenium import webdriver 2.import requests 3. from bs4 import Bea ...

  6. SP7258 SUBLEX - Lexicographical Substring Search(后缀自动机)

    传送门 解题思路 首先建\(sam\),然后在拓扑序上\(dp\)一下,把每个点的路径数算出来,然后统计答案时就在自动机上\(dfs\)一下,仿照平衡树那样找第\(k\)小. 代码 #include& ...

  7. sqlmap用户手册详解【实用版】

    网上的sqlmap教程很多,但是我自己备忘小笔记都是在我的电脑上存着了,万一我要出去玩的时候,有点忘了,还得再百度翻翻,还不如发到我自己知乎上,忘了立马一看就记着了.虽说我的sqlmap备忘小笔记汇总 ...

  8. 在Visual C++中使用内联汇编

    一.内联汇编的优缺点 因为在Visual C++中使用内联汇编不需要额外的编译器和联接器,且可以处理Visual C++中不能处理的一些事情,而且可以使用在C/C++中的变量,所以非常方便.内联汇编主 ...

  9. targetSdkVersion和与target属性的区别

    参考:http://blog.csdn.net/dai_zhenliang/article/details/8175781 AndroidMenifest.xml中targetSdkVersion和p ...

  10. (转)Linux环境进程间通信----系统 V 消息队列列

    转:http://www.ibm.com/developerworks/cn/linux/l-ipc/part3/ 消息队列(也叫做报文队列)能够克服早期unix通信机制的一些缺点.作为早期unix通 ...