【BZOJ 1036】[ZJOI2008]树的统计Count
【题目链接】:http://www.lydsy.com/JudgeOnline/problem.php?id=1036
【题意】
【题解】
树链剖分入门题;
每一条链维护一个线段树就好;
uppest数组维护这条链的最顶端的元素;
一条链一条链的往上走;直到两个点在同一条链里面了
balabala
【完整代码】
#include <bits/stdc++.h>
using namespace std;
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define LL long long
#define rep1(i,a,b) for (int i = a;i <= b;i++)
#define rep2(i,a,b) for (int i = a;i >= b;i--)
#define mp make_pair
#define pb push_back
#define fi first
#define se second
#define rei(x) scanf("%d",&x)
#define rel(x) scanf("%lld",&x)
#define ref(x) scanf("%lf",&x)
typedef pair<int, int> pii;
typedef pair<LL, LL> pll;
const int dx[9] = { 0,1,-1,0,0,-1,-1,1,1 };
const int dy[9] = { 0,0,0,-1,1,-1,1,-1,1 };
const double pi = acos(-1.0);
const int N = 3e4+100;
const int INF = 3e4 + 200;
int n,fa[N],siz[N],dep[N],uppest[N],bh[N],cnt;
int v[N],sum[N<<2],mx[N<<2];
vector <int> G[N];
void in()
{
rei(n);
rep1(i, 1, n - 1)
{
int x, y;
rei(x), rei(y);
G[x].pb(y), G[y].pb(x);
}
rep1(i, 1, n)
rei(v[i]);
}
void dfs1(int x)
{
int len = G[x].size();
siz[x] = 1;
rep1(i, 0, len - 1)
{
int y = G[x][i];
if (y == fa[x]) continue;
fa[y] = x;
dep[y] = dep[x] + 1;
dfs1(y);
siz[x] += siz[y];
}
}
void dfs2(int x, int chain)
{
int len = G[x].size();
int k = 0;
bh[x] = ++cnt;
uppest[x] = chain;
rep1(i, 0, len - 1)
{
int y = G[x][i];
if (dep[y]>dep[x] && siz[y] > siz[k])
k = y;
}
if (k == 0) return;
dfs2(k, chain);
rep1(i, 0, len - 1)
{
int y = G[x][i];
if (dep[y] > dep[x] && y != k)
dfs2(y, y);
}
}
void updata(int pos, int val,int l, int r, int rt)
{
if (l == r)
{
sum[rt] = mx[rt] = val;
return;
}
int m = (l + r) >> 1;
if (pos <= m)
updata(pos, val,lson);
else
updata(pos, val,rson);
sum[rt] = sum[rt << 1] + sum[rt << 1 | 1];
mx[rt] = max(mx[rt << 1], mx[rt << 1 | 1]);
}
int query_max(int L, int R, int l, int r, int rt)
{
if (L <= l && r <= R)
return mx[rt];
int m = (l + r) >> 1;
int temp1 = -INF;
if (L <= m)
temp1 = max(temp1, query_max(L, R, lson));
if (m < R)
temp1 = max(temp1, query_max(L, R, rson));
return temp1;
}
int get_max(int u, int v)
{
int t = -3e4 - 100;
while (uppest[u] != uppest[v])
{
if (dep[uppest[u]] < dep[uppest[v]])
swap(u, v);
t = max(t, query_max(bh[uppest[u]], bh[u], 1, n, 1));
u = fa[uppest[u]];
}
if (dep[u] < dep[v])
swap(u, v);
t = max(t, query_max(bh[v], bh[u], 1, n, 1));
return t;
}
int query_sum(int L, int R, int l, int r, int rt)
{
if (L <= l && r <= R)
return sum[rt];
int m = (l + r) >> 1;
int temp = 0;
if (L <= m)
temp += query_sum(L, R, lson);
if (m < R)
temp += query_sum(L, R, rson);
return temp;
}
int get_sum(int u, int v)
{
int t = 0;
while (uppest[u] != uppest[v])
{
if (dep[uppest[u]] < dep[uppest[v]])
swap(u, v);
t += query_sum(bh[uppest[u]], bh[u], 1, n, 1);
u = fa[uppest[u]];
}
if (dep[u] < dep[v])
swap(u, v);
t+=query_sum(bh[v], bh[u], 1, n, 1);
return t;
}
void get_ans()
{
rep1(i, 1, n)
updata(bh[i], v[i],1, n, 1);
int q;
rei(q);
char s[8];
rep1(i, 1, q)
{
scanf("%s", s);
if (s[0] == 'C')
{
int u, t;
rei(u), rei(t);
updata(bh[u], t, 1, n, 1);
}
else
{
int u, v;
rei(u), rei(v);
if (s[1] == 'M')
printf("%d\n", get_max(u, v));
else
printf("%d\n", get_sum(u, v));
}
}
}
int main()
{
//freopen("F:\\rush.txt", "r", stdin);
in();
dfs1(1);
dfs2(1, 1);
get_ans();
//printf("\n%.2lf sec \n", (double)clock() / CLOCKS_PER_SEC);
return 0;
}
【BZOJ 1036】[ZJOI2008]树的统计Count的更多相关文章
- BZOJ.1036 [ZJOI2008]树的统计Count ( 点权树链剖分 线段树维护和与最值)
BZOJ.1036 [ZJOI2008]树的统计Count (树链剖分 线段树维护和与最值) 题意分析 (题目图片来自于 这里) 第一道树链剖分的题目,谈一下自己的理解. 树链剖分能解决的问题是,题目 ...
- BZOJ 1036: [ZJOI2008]树的统计Count [树链剖分]【学习笔记】
1036: [ZJOI2008]树的统计Count Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 14302 Solved: 5779[Submit ...
- BZOJ 1036: [ZJOI2008]树的统计Count
1036: [ZJOI2008]树的统计Count Time Limit: 10 Sec Memory Limit: 162 MB Submit: 14354 Solved: 5802 [Subm ...
- bzoj 1036 [ZJOI2008]树的统计Count(树链剖分,线段树)
1036: [ZJOI2008]树的统计Count Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 10677 Solved: 4313[Submit ...
- Bzoj 1036: [ZJOI2008]树的统计Count 树链剖分,LCT
1036: [ZJOI2008]树的统计Count Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 11102 Solved: 4490[Submit ...
- 数据结构(LCT动态树):BZOJ 1036: [ZJOI2008]树的统计Count
1036: [ZJOI2008]树的统计Count Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 12266 Solved: 4945[Submit ...
- BZOJ 1036: [ZJOI2008]树的统计Count( 树链剖分 )
树链剖分... 不知道为什么跑这么慢 = = 调了一节课啊跪.. ------------------------------------------------------------------- ...
- bzoj 1036: [ZJOI2008]树的统计Count 树链剖分+线段树
1036: [ZJOI2008]树的统计Count Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 16294 Solved: 6645[Submit ...
- bzoj 1036: [ZJOI2008]树的统计Count (树链剖分+线段树 点权)
1036: [ZJOI2008]树的统计Count Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 21194 Solved: 8589[Submit ...
- BZOJ 1036: [ZJOI2008]树的统计Count (树链剖分模板题)
1036: [ZJOI2008]树的统计Count Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 14982 Solved: 6081[Submit ...
随机推荐
- Emgucv 图像操作笔记
这里记下一些学习过程中的心得和技巧.我用VS2008,C#的平台进行编写. 1.将图片载入PictureBox的方法: Image<Bgr, byte> img = new Image&l ...
- 调色板原理 & 编程
调色板原理 & 编程 逻辑调色板结构LOGPALETTE,该结构定义如下: typedef struct tagLOGPALETTE { WORD palVersion; //调色板的板本号, ...
- 【JAVASE】Java同一时候抛出多个异常
Java有异常抛出后.跳出程序.一般无法运行接下来的代码. 大家做登陆功能.常常会实username和password的登陆校验,username或者password错误.假设通常是提示usernam ...
- Dcloud开发webApp踩过的坑
Dcloud开发webApp踩过的坑 一.总结 一句话总结:HTML5+扩展了JavaScript对象plus,使得js可以调用各种浏览器无法实现或实现不佳的系统能力,设备能力如摄像头.陀螺仪.文件系 ...
- 关于http请求指定本地ip
static void Main(string[] args) { //ssl证书验证问题(没有校验) ServicePointManager.ServerCertificateValidationC ...
- Android Warning not all local changes may be shown due to an error
idea使用svn出现Warning not all local changes may be shown due to an error,如下图所示: 解决方案: 1.File > Setti ...
- 每日技术总结:setx,
1.setx命令设置环境变量 设置用户环境变量: setx NAME "XXX" 设置系统环境变量: setx NAME "XXX" /m
- 应用Python来计算排列中的逆序数个数
在一个排列中,如果一对数的前后位置与大小顺序相反,即前面的数大于后面的数,那么它们就称为一个逆序.一个排列中逆序的总数就称为这个排列的逆序数.一个排列中所有逆序总数叫做这个排列的逆序数.也就是说,对于 ...
- Eclipse "Could not create java virtual machine"的问题解决
今天到了新的环境,需要重新搭建Android的开发环境,下载eclipse并安装了JDK1.6后,启动eclipse,发现出现了错误“Could not create Javavirtual mach ...
- 8.3 Android灯光系统_编写HAL_lights.c
注意在led-classes.c中定义的led_class_attrs[]所建立的文件的属性应该改为0666,否则应用程序无权操作它 同时ledtrig-time.c里面对应新建的那几个delay_o ...