【Codeforces】Gym100633 D. LWDB
题解
点分治,然后每个点上挂着一个距离不超过\(a_{i}\)的颜色改成\(c\)
用一个单调栈维护距离单调递减,每次查询在每个包括这个点的分治中心的单调栈上二分,找到修改最靠前的颜色作为这个点的颜色
代码
#include <bits/stdc++.h>
#define fi first
#define se second
#define pii pair<int,int>
#define mp make_pair
#define pb push_back
#define space putchar(' ')
#define enter putchar('\n')
#define eps 1e-10
#define MAXN 200005
//#define ivorysi
using namespace std;
typedef long long int64;
typedef unsigned int u32;
typedef double db;
template<class T>
void read(T &res) {
res = 0;T f = 1;char c = getchar();
while(c < '0' || c > '9') {
if(c == '-') f = -1;
c = getchar();
}
while(c >= '0' && c <= '9') {
res = res * 10 +c - '0';
c = getchar();
}
res *= f;
}
template<class T>
void out(T x) {
if(x < 0) {x = -x;putchar('-');}
if(x >= 10) {
out(x / 10);
}
putchar('0' + x % 10);
}
struct ch {
int id,d,c;
};
struct node {
int to,next,val;
}E[MAXN * 2];
int N,head[MAXN],sumE,d[MAXN],M;
bool vis[MAXN];
vector<int> aux[MAXN],dep[MAXN],poi;
vector<ch> sta[MAXN];
void add(int u,int v,int c) {
E[++sumE].to = v;
E[sumE].next = head[u];
E[sumE].val = c;
head[u] = sumE;
}
int Calc_G(int st) {
static int fa[MAXN],son[MAXN],siz[MAXN],que[MAXN],ql,qr;
ql = 1,qr = 0;
que[++qr] = st;son[st] = 0;siz[st] = 1;fa[st] = 0;
while(ql <= qr) {
int u = que[ql++];
for(int i = head[u] ; i ; i = E[i].next) {
int v = E[i].to;
if(!vis[v] && v != fa[u]) {
que[++qr] = v;
siz[v] = 1;son[v] = 0;fa[v] = u;
}
}
}
int res = que[qr];
for(int i = qr ; i >= 1 ; --i) {
int u = que[i];
if(fa[u]) {
siz[fa[u]] += siz[u];
son[fa[u]] = max(son[fa[u]],siz[u]);
}
son[u] = max(son[u],qr - siz[u]);
if(son[u] < son[res]) res = u;
}
return res;
}
void dfs_for_dep(int u,int fa) {
poi.pb(u);
for(int i = head[u] ; i ; i = E[i].next) {
int v = E[i].to;
if(!vis[v] && v != fa) {
d[v] = d[u] + E[i].val;
dfs_for_dep(v,u);
}
}
}
void dfs_divide(int u) {
int G = Calc_G(u);
vis[G] = 1;
sta[G].pb((ch){0,1000000000,0});
d[G] = 0;poi.clear();
dfs_for_dep(G,0);
for(int i = 0 ; i < poi.size() ; ++i) {
aux[poi[i]].pb(G);
dep[poi[i]].pb(d[poi[i]]);
}
for(int i = head[G] ; i ; i = E[i].next) {
int v = E[i].to;
if(!vis[v]) dfs_divide(v);
}
}
void Init() {
read(N);
int u,v,c;
for(int i = 1 ; i < N ; ++i) {
read(u);read(v);read(c);
add(u,v,c);add(v,u,c);
}
dfs_divide(1);
}
void Change(int id,int x,int d,int c) {
for(int i = aux[x].size() - 1 ; i >= 0 ; --i) {
int u = aux[x][i],t = d - dep[x][i];
if(t < 0) continue;
while(sta[u].size()) {
ch l = sta[u].back();
if(l.d <= t) sta[u].pop_back();
else break;
}
sta[u].pb((ch){id,t,c});
}
}
int Query(int x) {
int id = 0,c = 0;
for(int i = aux[x].size() - 1 ; i >= 0 ; --i) {
int u = aux[x][i],d = dep[x][i];
int L = 0,R = sta[u].size() - 1;
while(L < R) {
int mid = (L + R + 1) >> 1;
if(sta[u][mid].d >= d) L = mid;
else R = mid - 1;
}
if(sta[u][L].id > id) {id = sta[u][L].id;c = sta[u][L].c;}
}
return c;
}
void Solve() {
read(M);
int op,v,d,c;
for(int i = 1 ; i <= M ; ++i) {
read(op);read(v);
if(op == 1) {
read(d);read(c);
Change(i,v,d,c);
}
else {
out(Query(v));enter;
}
}
}
int main() {
#ifdef ivorysi
freopen("f1.in","r",stdin);
#endif
Init();
Solve();
}
【Codeforces】Gym100633 D. LWDB的更多相关文章
- 【Codeforces】Round #491 (Div. 2) 总结
[Codeforces]Round #491 (Div. 2) 总结 这次尴尬了,D题fst,E没有做出来.... 不过还好,rating只掉了30,总体来说比较不稳,下次加油 A:If at fir ...
- 【Codeforces】Round #488 (Div. 2) 总结
[Codeforces]Round #488 (Div. 2) 总结 比较僵硬的一场,还是手速不够,但是作为正式成为竞赛生的第一场比赛还是比较圆满的,起码没有FST,A掉ABCD,总排82,怒涨rat ...
- 【CodeForces】601 D. Acyclic Organic Compounds
[题目]D. Acyclic Organic Compounds [题意]给定一棵带点权树,每个点有一个字符,定义一个结点的字符串数为往下延伸能得到的不重复字符串数,求min(点权+字符串数),n&l ...
- 【Codeforces】849D. Rooter's Song
[算法]模拟 [题意]http://codeforces.com/contest/849/problem/D 给定n个点从x轴或y轴的位置p时间t出发,相遇后按对方路径走,问每个数字撞到墙的位置.(还 ...
- 【CodeForces】983 E. NN country 树上倍增+二维数点
[题目]E. NN country [题意]给定n个点的树和m条链,q次询问一条链(a,b)最少被多少条给定的链覆盖.\(n,m,q \leq 2*10^5\). [算法]树上倍增+二维数点(树状数组 ...
- 【CodeForces】925 C.Big Secret 异或
[题目]C.Big Secret [题意]给定数组b,求重排列b数组使其前缀异或和数组a单调递增.\(n \leq 10^5,1 \leq b_i \leq 2^{60}\). [算法]异或 为了拆位 ...
- 【CodeForces】700 D. Huffman Coding on Segment 哈夫曼树+莫队+分块
[题目]D. Huffman Coding on Segment [题意]给定n个数字,m次询问区间[l,r]的数字的哈夫曼编码总长.1<=n,m,ai<=10^5. [算法]哈夫曼树+莫 ...
- 【CodeForces】906 D. Power Tower 扩展欧拉定理
[题目]D. Power Tower [题意]给定长度为n的正整数序列和模数m,q次询问区间[l,r]累乘幂%m的答案.n,q<=10^5,m,ai<=10^9. [算法]扩展欧拉定理 [ ...
- 【CodeForces】741 D. Arpa’s letter-marked tree and Mehrdad’s Dokhtar-kosh paths(dsu on tree)
[题意]给定n个点的树,每条边有一个小写字母a~v,求每棵子树内的最长回文路径,回文路径定义为路径上所有字母存在一种排列为回文串.n<=5*10^5. [算法]dsu on tree [题解]这 ...
随机推荐
- bigfile tablespace
背景 这次终于有个linux实际迁移oracle的机会了,之前都是学习实验.想起最早时,都是windows搞oracle,又让我想起多年期一个项目,数据量太大及计算逻辑太复杂,我用存储过程 ...
- $.each() 与 $(selector).each()的区别
$.each( dataArr,function(i,item){}) 可用于遍历任何的集合(无论是数组或对象). 如果是数组,回调函数每次传入数组的索引(也就是i)和对应的值(item)(值亦可以 ...
- 基于数组的循环队列(C++模板实现)
循环队列使用数组实现的话,简单.方便.之前实现的队列,当尾端索引到达队列最后的时候,无论前面是否还有空间,都不能再添加数据了.循环队列使得队列的存储单元可以循环利用,它需要一个额外的存储单元来判断队列 ...
- JMeter进行一次简单的压力测试
测试目的:10个用户并发打开百度首页(https://www.baidu.com/),百度能否正常响应. 操作步骤 一.打开JMeter 打开后的界面如下: 二.右击“测试计划”,添加线程组 三.设置 ...
- day10 函数
函数基础 函数概念 为什么用函数 什么是函数 定义函数 调用函数 返回值详解上节回顾 文件处理 修改文件 1.读取要修改文件内容 read可能导致内存溢出 赋值给变量 修改 将修改后的内容重新写入文件 ...
- AngularJs中,如何在ng-repeat完成之后,执行Js脚本
//ng-repeat生成4个li,生成后再执行自定义方法fn在每个li后加一根横线 <script> var myapp=angular.module('myapp',[]); myap ...
- kali linux 安装wps office
1.下载wps for linux 版本 wget http://kdl.cc.ksosoft.com/wps-community/download/6757/wps-office_10.1.0.67 ...
- CF558E
非常好的一道题,是线段树的常见玩法 将字符串转化为1~26个数 对区间开一棵线段树,用两个数组分别维护区间中1~26每个数的个数以及一个区间覆盖标记,表示这个区间是否被某一个值覆盖了 在每次排序时,首 ...
- flower
问题 D: flower 时间限制: 1 Sec 内存限制: 128 MB 题目描述 又是一年教师节,有n个小朋友打算去看望花老师.去看花老师当然要买花咯,不过某些土(xue)豪(ba)买了太多的花 ...
- WebStorm中常用的快捷键及使用技巧
------------------------------------- 近期整理了如下个人觉得比较常用的快捷键,也请前辈给予补充.多多指教. --------------------------- ...