【题目链接】

点击打开链接

【算法】

树链剖分

每个宗教建一棵线段树,注意数据量大,要动态开点

【代码】

#include<bits/stdc++.h>
using namespace std;
#define MAXLOG 18
const int MAXN = 1e5 + ;
const int MAXS = 1e7 + ; int i,n,q,x,y,t,Lca,SZ,timer;
int w[MAXN],c[MAXN],son[MAXN],dfn[MAXN],top[MAXN],size[MAXN],anc[MAXN][MAXLOG],
dep[MAXN],fa[MAXN],lc[MAXS],rc[MAXS],sum[MAXS],Max[MAXS],root[MAXN];
vector<int> e[MAXN];
char opt[]; inline void dfs1(int x)
{
int i,y;
anc[x][] = fa[x];
for (i = ; i < MAXLOG; i++)
{
if (dep[x] < ( << i)) break;
anc[x][i] = anc[anc[x][i-]][i-];
}
size[x] = ;
for (i = ; i < e[x].size(); i++)
{
y = e[x][i];
if (fa[x] != y)
{
dep[y] = dep[x] + ;
fa[y] = x;
dfs1(y);
size[x] += size[y];
if (size[y] > size[son[x]]) son[x] = y;
}
}
}
inline void dfs2(int x,int tp)
{
int i,y;
dfn[x] = ++timer;
top[x] = tp;
if (son[x]) dfs2(son[x],tp);
for (i = ; i < e[x].size(); i++)
{
y = e[x][i];
if (fa[x] != y && son[x] != y) dfs2(y,y);
}
}
inline int lca(int x,int y)
{
int i,t;
if (dep[x] > dep[y]) swap(x,y);
t = dep[y] - dep[x];
for (i = ; i < MAXLOG; i++)
{
if (t & ( << i))
y = anc[y][i];
}
if (x == y) return x;
for (i = MAXLOG - ; i >= ; i--)
{
if (anc[x][i] != anc[y][i])
{
x = anc[x][i];
y = anc[y][i];
}
}
return fa[x];
}
inline void push_up(int root)
{
Max[root] = max(Max[lc[root]],Max[rc[root]]);
sum[root] = sum[lc[root]] + sum[rc[root]];
}
inline void modify(int &root,int l,int r,int x,int val)
{
int mid;
if (!root) root = ++SZ;
if (l == r)
{
Max[root] = sum[root] = val;
return;
}
mid = (l + r) >> ;
if (mid >= x) modify(lc[root],l,mid,x,val);
else modify(rc[root],mid+,r,x,val);
push_up(root);
}
inline int query_max(int root,int l,int r,int ql,int qr)
{
int mid;
if (!root) return ;
if (l == ql && r == qr) return Max[root];
mid = (l + r) >> ;
if (mid >= qr) return query_max(lc[root],l,mid,ql,qr);
else if (mid + <= ql) return query_max(rc[root],mid+,r,ql,qr);
else return max(query_max(lc[root],l,mid,ql,mid),query_max(rc[root],mid+,r,mid+,qr));
}
inline int query_sum(int root,int l,int r,int ql,int qr)
{
int mid;
if (!root) return ;
if (l == ql && r == qr) return sum[root];
mid = (l + r) >> ;
if (mid >= qr) return query_sum(lc[root],l,mid,ql,qr);
else if (mid + <= ql) return query_sum(rc[root],mid+,r,ql,qr);
else return query_sum(lc[root],l,mid,ql,mid) + query_sum(rc[root],mid+,r,mid+,qr);
} inline int solve1(int c,int x,int y)
{
int ans = ,
tx = top[x],ty = top[y];
while (tx != ty)
{
ans = max(ans,query_max(root[c],,n,dfn[tx],dfn[x]));
x = fa[tx]; tx = top[x];
}
ans = max(ans,query_max(root[c],,n,dfn[y],dfn[x]));
return ans;
}
inline int solve2(int c,int x,int y)
{
int ans = ,
tx = top[x],ty = top[y];
while (tx != ty)
{
ans += query_sum(root[c],,n,dfn[tx],dfn[x]);
x = fa[tx]; tx = top[x];
}
ans += query_sum(root[c],,n,dfn[y],dfn[x]);
return ans;
} int main()
{ scanf("%d%d",&n,&q);
for (i = ; i <= n; i++) scanf("%d%d",&w[i],&c[i]);
for (i = ; i < n; i++)
{
scanf("%d%d",&x,&y);
e[x].push_back(y);
e[y].push_back(x);
}
dfs1();
dfs2(,);
for (i = ; i <= n; i++) modify(root[c[i]],,n,dfn[i],w[i]);
while (q--)
{
scanf("%s",&opt);
if (strcmp(opt,"CC") == )
{
scanf("%d%d",&x,&y);
modify(root[c[x]],,n,dfn[x],);
c[x] = y;
modify(root[c[x]],,n,dfn[x],w[x]);
}
if (strcmp(opt,"CW") == )
{
scanf("%d%d",&x,&y);
modify(root[c[x]],,n,dfn[x],y);
w[x] = y;
}
if (strcmp(opt,"QS") == )
{
scanf("%d%d",&x,&y);
Lca = lca(x,y);
t = solve2(c[x],x,Lca) + solve2(c[x],y,Lca);
if (c[Lca] == c[x]) t -= w[Lca];
printf("%d\n",t);
}
if (strcmp(opt,"QM") == )
{
scanf("%d%d",&x,&y);
Lca = lca(x,y);
printf("%d\n",max(solve1(c[x],x,Lca),solve1(c[x],y,Lca)));
}
} return ; }

【SDOI 2014】 旅行的更多相关文章

  1. 【BZOJ 3531】【SDOI 2014】旅行

    因为有$10^5$个宗教,需要开$10^5$个线段树. 平时开的线段树是“满”二叉树,但在这个题中代表一个宗教的线段树管辖的区间有很多点都不属于这个宗教,也就不用“把枝叶伸到这个点上”,所以这样用类似 ...

  2. 【BZOJ 3529】【SDOI 2014】数表

    看Yveh的题解,这道题卡了好长时间,一直不明白为什么要······算了当时太naive我现在都不好意思说了 #include<cstdio> #include<cstring> ...

  3. [BZOJ 3530][Sdoi 2014]数数

    阿拉~好像最近总是做到 AC 自动机的题目呢喵~ 题目的算法似乎马上就能猜到的样子…… AC 自动机 + 数位 dp 先暴力转移出 f[i][j] :表示从 AC 自动机上第 j 号节点走 i 步且不 ...

  4. BZOJ 3533 sdoi 2014 向量集

    设(x,y)为Q的查询点,分类讨论如下:1.y>0:  最大化a*x+b*y,维护一个上凸壳三分即可 2.y<0:最大化a*x+b*y  维护一个下凸壳三分即可 我们考虑对时间建出一棵线段 ...

  5. [SDOI 2014]数表

    Description 有一张N×m的数表,其第i行第j列(1 < =i < =N,1 < =j < =m)的数值为 能同时整除i和j的所有自然数之和.给定a,计算数表中不大于 ...

  6. 解题:SDOI 2014 重建

    题面 做这个这个题需要稍微深入理解一点矩阵树定理:套矩阵树定理得到的东西是有意义的,它是“所有生成树边权乘积之和”(因为度数矩阵是点的边权和,邻接矩阵是边权),即$\sum_{t}\prod_{e∈t ...

  7. 解题:SDOI 2014 数表

    题面 为了好写式子,先不管$a$的限制 设$facs$为因子和,那么有 $ans=\sum\limits_{i=1}^n\sum\limits_{j=1}^mfacs(gcd(i,j))$ 再设$f( ...

  8. 【BZOJ 3530】【SDOI 2014】数数

    http://www.lydsy.com/JudgeOnline/problem.php?id=3530 上午gty的测试题,爆0了qwq 类似文本生成器那道题,把AC自动机的转移建出来,准确地说建出 ...

  9. 「BZOJ 3529」「SDOI 2014」数表「莫比乌斯反演」

    题意 有一张 \(n\times m\) 的数表,其第\(i\)行第\(j\)列的数值为能同时整除\(i\)和\(j\)的所有自然数之和. \(T\)组数据,询问对于给定的 \(n,m,a\) , 计 ...

随机推荐

  1. Android TransitionDrawable:过渡动画Drawable

    Android TransitionDrawable实现一种可以用动画表示的Drawable.写一个例子. package zhangphil.app; import android.graphics ...

  2. Sql Server数据库视图的创建、修改

    if OBJECT_ID('Sales.USACusts') is not null drop view Sales.USACusts; go create view Sales.USACusts a ...

  3. Hotel(poj 3667)

    题意:询问区间最长连续空串 /* 用线段树维护区间最长连续左空串和右空串 */ #include<cstdio> #include<iostream> #define N 50 ...

  4. 洛谷—— P1785 漂亮的绝杀

    https://www.luogu.org/problem/show?pid=1785 题目背景 话说absi2011的企鹅在和斗神塔第60层的Boss战斗 不好,这局要输了,企鹅还剩4血了Boss还 ...

  5. P2863 [USACO06JAN]牛的舞会The Cow Prom

    洛谷——P2863 [USACO06JAN]牛的舞会The Cow Prom 题目描述 The N (2 <= N <= 10,000) cows are so excited: it's ...

  6. R-Tree空间索引算法的研究历程和最新进展分析

    转自原文 R-Tree空间索引算法的研究历程和最新进展分析,2008 摘要:本文介绍了空间索引的概念.R-Tree数据结构和R-Tree空间索引的算法描述,并从R-Tree索引技术的优缺点对R-Tre ...

  7. 从头开始学Android之(一)——— Android架构

    从事Android开发已经两年多了,最近项目上特别清闲,刚开始时在闲暇的时候都不知道干嘛,整天混日子.有一天突然有个以前同学找到我,说要我帮忙做一个Android的需求,就是在后台截屏(涉及到服务以及 ...

  8. QT窗体间传值总结之Signal&Slot

    在写程序时,难免会碰到多窗体之间进行传值的问题.依照自己的理解,我把多窗体传值的可以使用的方法归纳如下: 1.使用QT中的Signal&Slot机制进行传值: 2.使用全局变量: 3.使用pu ...

  9. request.getAttribute()与request.setAttribute()

    request.getAttribute()与request.setAttribute() request.getAttribute("nameOfObj")可得到JSP页面一表单 ...

  10. 算法导论学习之线性时间求第k小元素+堆思想求前k大元素

    对于曾经,假设要我求第k小元素.或者是求前k大元素,我可能会将元素先排序,然后就直接求出来了,可是如今有了更好的思路. 一.线性时间内求第k小元素 这个算法又是一个基于分治思想的算法. 其详细的分治思 ...