bzoj1036题解
【解题思路】
直接上树剖套线段树/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题解的更多相关文章
- BZOJ1036[ZJOI2008]树的统计Count 题解
题目大意: 一棵树上有n个节点,编号分别为1到n,每个节点都有一个权值w.有一些操作:1.把结点u的权值改为t:2.询问从点u到点v的路径上的节点的最大权值 3.询问从点u到点v的路径上的节点的权值和 ...
- BZOJ1036:[ZJOI2008]树的统计——题解
http://www.lydsy.com/JudgeOnline/problem.php?id=1036 题目描述 一棵树上有n个节点,编号分别为1到n,每个节点都有一个权值w. 我们将以下面的形式来 ...
- 【BZOJ1036】[ZJOI2008]树的统计Count 树链剖分
[BZOJ1036][ZJOI2008]树的统计Count Description 一棵树上有n个节点,编号分别为1到n,每个节点都有一个权值w.我们将以下面的形式来要求你对这棵树完成一些操作: I. ...
- 【bzoj1036】 ZJOI2008—树的统计Count
http://www.lydsy.com/JudgeOnline/problem.php?id=1036 (题目链接) 题意 动态维护树上两点间最大权值和权值和. Solution 裸树链剖分. 这一 ...
- BZOJ1036 [ZJOI2008]树的统计Count 树链剖分
欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - BZOJ1036 题意概括 一个树,每个节点有一个权值.3种操作. 1:修改某一个节点的权值. 2:询问某两个 ...
- 2016 华南师大ACM校赛 SCNUCPC 非官方题解
我要举报本次校赛出题人的消极出题!!! 官方题解请戳:http://3.scnuacm2015.sinaapp.com/?p=89(其实就是一堆代码没有题解) A. 树链剖分数据结构板题 题目大意:我 ...
- noip2016十连测题解
以下代码为了阅读方便,省去以下头文件: #include <iostream> #include <stdio.h> #include <math.h> #incl ...
- BZOJ-2561-最小生成树 题解(最小割)
2561: 最小生成树(题解) Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 1628 Solved: 786 传送门:http://www.lyd ...
- Codeforces Round #353 (Div. 2) ABCDE 题解 python
Problems # Name A Infinite Sequence standard input/output 1 s, 256 MB x3509 B Restoring P ...
随机推荐
- kindeditor加入方法
1.editor文件夹拷进来 2. editor里jsp子文件夹里找到几个jar拷贝到网站的web-app里的lib下 3. 网页里 head里加个这个 <link rel="sty ...
- mybatis调用存储过程(@Select方式)
存储过程还不会写的同学可以参考我另一篇文章:https://www.cnblogs.com/liuboyuan/p/9375882.html 网上已经有很多用mybatis调用的教程了,但是大部分是x ...
- 【基础】Pipeline
1. 参考的优秀文章 Request/Response protocols and RTT 2. 来源 原来,系统中一个树结构的数据来源是Redis,由于数据增多.业务复杂,查询速度并不快.究其原因, ...
- PHP FILTER_UNSAFE_RAW 过滤器
定义和用法 FILTER_UNSAFE_RAW 过滤器不进行任何过滤,去除或编码特殊字符. 该过滤器删除那些对应用程序有潜在危害的数据.它用于去除标签以及删除或编码不需要的字符. 如果不规定标志,则该 ...
- bzoj1044题解
[题意分析] 本题等价于如下描述: 有一个长度为n的正整数序列,要求将其分解成m+1个子串,使最大子串和最小.求这个最大子串和及对应的分解方案数. [解题思路] 第一问二分+贪心即可.容易证明对于确定 ...
- IReport实践指南
IReport实践指南 前言 最近,在做一个电子签章的功能,然后就接触到IReport报表,经过好几天的摸索实践,功能已经完成了,今天来总结一下. 什么是IReport,IReport是JasperR ...
- Hbase的rowkey设计
HBase的rowKey设计技巧 1.设计宗旨与目标 主要目的就是针对特定的业务模型,按照rowKey进行预分区设计,使之后面加入的数据能够尽可能的分散于不同的rowKey中.比如复合RowKey. ...
- 用C语言实现yield
用C语言实现yield C/C++中没有yield语法,有的时候想用产生器,自己实现一个循环会感觉很麻烦.C/C++应该如何实现产生器呢? class FibonacciGenerator { pub ...
- 关于BUG管理工具的操作总结。(禅道)
禅道是第一款国产的优秀开源项目管理软件.先进的管理思想,合理的软件架构,简洁实效的操作,优雅的代码实现,灵活的扩展机制,强大而易用的api 调用机制,多语言支持,多风格支持,搜索功能,统计功能——这一 ...
- 架构-软件系统体系结构-C/S架构:C/S架构
ylbtech-架构-软件系统体系结构-C/S架构:C/S架构 Client/Server架构,即客户端/服务器架构.是大家熟知的软件系统体系结构,通过将任务合理分配到Client端和Server端, ...