【解题思路】

  直接上树剖套线段树/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. AtomicInteger 、Synchronized 和 volatile 之间的区别?

    AtomicInteger:无锁的线程安全整数??? Synchronized:同步 volatile:挥发性??? 参考文档:

  2. Delphi 窗体函数 ShowScrollBar 控制滚动条

    API函数 函数来源:FUNCTION ulong ShowScrollBar(ulong hwnd,ulong wBar,ulong bShow) LIBRARY "user32.dll& ...

  3. CSS格式化---属性排序

    一.背景 与同事合作开发一个项目,后面修改 CSS 时,发现属性顺序跟我写的不一样 我从事开发前端时,导师是有给我大概指定了一定的书写规范 现在开发时,看到的 CSS 属性排序不一样,看起来有点难受( ...

  4. NGINX配置之一:日志篇

    打开nginx.conf配置文件: vi /usr/local/nginx/conf/nginx.conf 日志部分内容: 日志生成的到Nginx根目录logs/access.log文件,默认使用“m ...

  5. 1242 斐波那契数列的第N项

    1242 斐波那契数列的第N项  基准时间限制:1 秒 空间限制:131072 KB 分值: 0 难度:基础题   斐波那契数列的定义如下:   F(0) = 0 F(1) = 1 F(n) = F( ...

  6. 1、Appium Desktop介绍

    Appium Desktop是一款适用于Mac,Windows和Linux的开源应用程序,它以美观而灵活的用户界面为您提供Appium自动化服务器的强大功能.它是几个Appium相关工具的组合: Ap ...

  7. Python 变量作用域 LEGB (下)—— Enclosing function locals

    上篇:Python 变量作用域 LEGB (上)—— Local,Global,Builtin https://www.cnblogs.com/yvivid/p/python_LEGB_1.html ...

  8. vue on emit 父子之间传值应用详细代码

    大概很多人都知道用这个,网上教程也一大堆,但我想说的是一定要手动敲一遍,敲一遍,敲一遍,重要的事情说三遍. 大概有些人也不知道它该何时用on,或者emit 的吧? 先说两个我项目中用到的场景吧: 项目 ...

  9. 无法CREATE UNIQUE INDEX;找到重复的关键字

  10. mysql的各种锁简单总结

    表总体上分为三种: 1.表锁 Myisam 开销小,并发低,加锁快,不会出现死锁问题:锁粒度大,发生锁冲突的概率最高. 2.行锁 innodb  开销大,并发高,加锁慢,会出现死锁问题:锁粒度小,发生 ...