这题的复杂度可以到达惊人的\(\log^4\)据说还能跑过去(差点没吓死我

直接二分+树剖树套树(\(n \log^4 n\))

一个\(\log\)也不少的4\(\log\)

但是我有个\(\log^3\)的树剖上面整体二分+线段树的做法

不过据说有个\(\log\)做法,我不会,反正我菜就是了

然后的话 就直接考虑个消除贡献…然而并不需要排序

权值线段树 就可以了

每次添加修改就

        if(! op) {
int y = read() , z = read() ;
Q[++ tot] = { 0 , -1 , val[y] , y , 1 } ; val[y] = z ;
Q[++ tot] = { 0 , 1 , val[y] , y , 1 } ; b[++ len] = z ;
} else {
int y = read() , z = read() ; Q[++ tot] = { y , z , op , ++ pos , 2} ;
}

然后就成功完成了打消贡献以及添加贡献

然后整体二分板子即可

#include <bits/stdc++.h>
#define int long long
#define rep(a , b , c) for(int a = b ; a <= c ; ++ a)
#define Rep(a , b , c) for(int a = b ; a >= c ; -- a)
#define go(u) for(int i = G.head[u] , v = G.to[i] , w = G.dis[i] ; i ; v = G.to[i = G.nxt[i]] , w = G.dis[i])
using namespace std ;
using ll = long long ;
using pii = pair < int , int > ;
using vi = vector < int > ;
int read() {
int x = 0 ; bool f = 1 ; char c = getchar() ;
while(c < 48 || c > 57) {
if(c == '-') f = 0 ;
c = getchar() ;
}
while(c > 47 && c < 58) {
x = (x << 1) + (x << 3) + (c & 15) ;
c = getchar() ;
}
return f ? x : -x ;
}
template <class T> void print(T x , char c = '\n') {
static char st[100] ; int stp = 0 ;
if(! x) putchar('0') ; if(x < 0) x = -x , putchar('-') ;
while(x) st[++ stp] = x % 10 ^ 48 , x /= 10 ;
while(stp) putchar(st[stp --]) ; putchar(c) ;
}
template <class T> void cmax(T & x , T y) { x < y ? x = y : 0 ; }
template <class T> void cmin(T & x , T y) { x > y ? x = y : 0 ; }
const int _N = 1e6 + 10 ;
struct Group {
int head[_N] , nxt[_N << 1] , to[_N] , dis[_N] , cnt = 1 ;
Group () { memset(head , 0 , sizeof(head)) ; }
void add(int u , int v , int w = 1) { nxt[++ cnt] = head[u] ; to[cnt] = v ; dis[cnt] = w ; head[u] = cnt ; }
} ;
const int N = 5e5 + 10 ;
typedef int arr[N] ;
Group G ;
int n , q , len = 0 , val[N] , b[N << 1] ;
arr fa , d , son , sz ;
void dfs(int u) {
sz[u] = 1 ; go(u) if(v ^ fa[u]) {
fa[v] = u , d[v] = d[u] + 1 , dfs(v) , sz[u] += sz[v] ;
if(sz[v] > sz[son[u]]) son[u] = v ;
}
}
arr top , id ;
int idx = 0 ;
void dfs(int u , int t) {
top[u] = t ;
id[u] = ++ idx ;
if(son[u]) dfs(son[u] , t) ;
go(u) if(v ^ fa[u] && v ^ son[u]) dfs(v , v) ;
}
struct Seg {
int sum[N << 2] ;
void change(int l , int r , int rt , int pos , int val) {
if(l == r) { sum[rt] += val ; return ; }
int mid = l + r >> 1 ;
if(pos <= mid) change(l , mid , rt << 1 , pos , val) ;
else change(mid + 1 , r , rt << 1 | 1 , pos , val) ;
sum[rt] = sum[rt << 1] + sum[rt << 1 | 1] ;
}
int query(int a , int b , int l , int r , int rt) {
if(a <= l && r <= b) return sum[rt] ;
int mid = l + r >> 1 , ans = 0 ;
if(a <= mid) ans += query(a , b , l , mid , rt << 1) ;
if(b > mid) ans += query(a , b , mid + 1 , r , rt << 1 | 1) ;
return ans ;
}
} t ;
int query_range(int x , int y) {
int ans = 0 ;
while(top[x] != top[y]) { if(d[top[x]] < d[top[y]]) swap(x , y) ; ans += t.query(id[top[x]] , id[x] , 1 , n , 1) ; x = fa[top[x]] ; }
if(d[x] > d[y]) swap(x , y) ; ans += t.query(id[x] , id[y] , 1 , n , 1) ;
return ans ;
}
struct Query {
int x , y , k , id , type ;
} Q[N] , q1[N] , q2[N] ;
int tot = 0 , num = 0 , pos = 0 ;
arr ans ;
void solve(int L , int R , int l , int r) {
if(L > R) return ;
if(l == r) {
rep(i , L , R) if(Q[i].type == 2) ans[Q[i].id] = l ; return ;
}
int mid = l + r >> 1 , cnt1 = 0 , cnt2 = 0 ;
rep(i , L , R) {
if(Q[i].type == 1) {
if(Q[i].k > mid) {
t.change(1 , n , 1 , id[Q[i].id] , Q[i].y) ; q2[++ cnt2] = Q[i] ;
} else q1[++ cnt1] = Q[i] ;
} else {
int res = query_range(Q[i].x , Q[i].y) ;
if(res >= Q[i].k) q2[++ cnt2] = Q[i] ;
else { Q[i].k -= res ; q1[++ cnt1] = Q[i] ; }
}
}
rep(i , 1 , cnt2) if(q2[i].type == 1) t.change(1 , n , 1 , id[q2[i].id] , -q2[i].y) ;
rep(i , 1 , cnt1) Q[L + i - 1] = q1[i] ; rep(i , 1 , cnt2) Q[L + cnt1 + i - 1] = q2[i] ;
solve(L , L + cnt1 - 1 , l , mid) ; solve(L + cnt1 , R , mid + 1 , r) ;
}
signed main() {
n = read() ; q = read() ;
rep(i , 1 , n) { val[i] = read() ; Q[++ tot] = { 0 , 1 , val[i] , i , 1 } ; b[++ len] = val[i] ; }
rep(i , 2 , n) { int x = read() , y = read() ; G.add(x , y) ; G.add(y , x) ; }
dfs(1) ; dfs(1 , 1) ;
rep(i , 1 , q) {
int op = read() ;
if(! op) {
int y = read() , z = read() ;
Q[++ tot] = { 0 , -1 , val[y] , y , 1 } ; val[y] = z ;
Q[++ tot] = { 0 , 1 , val[y] , y , 1 } ; b[++ len] = z ;
} else {
int y = read() , z = read() ; Q[++ tot] = { y , z , op , ++ pos , 2} ;
}
}
sort(b + 1 , b + len + 1) , len = unique(b + 1 , b + len + 1) - b - 1 ;
rep(i , 1 , tot) if(Q[i].type != 2) Q[i].k = lower_bound(b + 1 , b + len + 1 , Q[i].k) - b ;
solve(1 , tot , 0 , len + 1) ;
rep(i , 1 , pos) {
if(! ans[i]) puts("invalid request!") ;
else print(b[ans[i]]) ;
}
return 0 ;
}

[CTSC2008]网络管理 [树剖+整体二分]的更多相关文章

  1. 2019.01.13 bzoj1146: [CTSC2008]网络管理Network(整体二分+树剖)

    传送门 题意简述:给一棵树,支持单点修改,询问路径上两点间第kkk大值. 思路: 读懂题之后立马可以想到序列上带修区间kkk大数的整体二分做法,就是用一个bitbitbit来支持查值. 那么这个题把树 ...

  2. P4175 [CTSC2008]网络管理 树剖+树套树

    $ \color{#0066ff}{ 题目描述 }$ M公司是一个非常庞大的跨国公司,在许多国家都设有它的下属分支机构或部门.为了让分布在世界各地的N个部门之间协同工作,公司搭建了一个连接整个公司的通 ...

  3. bzoj 1146 网络管理Network (CDQ 整体二分 + 树刨)

    题目传送门 题意:求树上路径可修改的第k大值是多少. 题解:CDQ整体二分+树刨. 每一个位置上的数都会有一段持续区间 根据CDQ拆的思维,可以将这个数拆成出现的时间点和消失的时间点. 然后通过整体二 ...

  4. BZOJ4538 HNOI2016网络(树链剖分+线段树+堆/整体二分+树上差分)

    某两个点间的请求只对不在这条路径上的询问有影响.那么容易想到每次修改除该路径上的所有点的答案.对每个点建个两个堆,其中一个用来删除,线段树维护即可.由于一条路径在树剖后的dfs序中是log个区间,所以 ...

  5. 洛谷P4332 [SHOI2014]三叉神经树(LCT,树剖,二分查找,拓扑排序)

    洛谷题目传送门 你谷无题解于是来补一发 随便百度题解,发现了不少诸如树剖\(log^3\)LCT\(log^2\)的可怕描述...... 于是来想想怎么利用题目的性质,把复杂度降下来. 首先,每个点的 ...

  6. 【bzoj2738】矩阵乘法 整体二分+二维树状数组

    题目描述 给你一个N*N的矩阵,不用算矩阵乘法,但是每次询问一个子矩形的第K小数. 输入 第一行两个数N,Q,表示矩阵大小和询问组数:接下来N行N列一共N*N个数,表示这个矩阵:再接下来Q行每行5个数 ...

  7. 整体二分--BZOJ1901: Zju2112 Dynamic Rankings

    n<=10000个数有m<=10000个操作,1.询问一个区间的第k小的数:2.单点修改. 带修主席树. 整体二分. 整体二分的必要条件: #include<string.h> ...

  8. [CTSC2008]网络管理(整体二分+树剖+树状数组)

    一道经典的带修改树链第 \(k\) 大的问题. 我只想出三个 \(\log\) 的解法... 整体二分+树剖+树状数组. 那不是暴力随便踩的吗??? 不过跑得挺快的. \(Code\ Below:\) ...

  9. 【BZOJ1146】【CTSC2008】网络管理 [整体二分]

    网络管理 Time Limit: 50 Sec  Memory Limit: 162 MB[Submit][Status][Discuss] Description M公司是一个非常庞大的跨国公司,在 ...

随机推荐

  1. BZOJ 1087 [SCOI2005]互不侵犯King(状压DP)

    题意:在N×N的棋盘里面放K个国王,使他们互不攻击,共有多少种摆放方案.国王能攻击到它上下左右,以及左上左下右上右下八个方向上附近的各一个格子,共8个格子.n<=9 思路:状压dp,dp[i][ ...

  2. UVA5913 Dictionary Sizes(字典树)(转载)

    题目大意:给出n个旧单词,要从这n个旧单词中构造新单词.构造条件是 S = Sa + Sb,其中Sa为某个旧单词的非空前缀,Sb为某个单词的非空后缀.求所有的新单词和旧单词中有多少个不同的单词. 思路 ...

  3. 机器学习(ML)十之CNN

    CNN-二维卷积层 卷积神经网络(convolutional neural network)是含有卷积层(convolutional layer)的神经网络.卷积神经网络均使用最常见的二维卷积层.它有 ...

  4. 全局new和宏结合起来的一个小应用

    #include <iostream> using namespace std; void* operator new(size_t size, const char* file, int ...

  5. 总结JavaScript对象的深浅拷贝

    十四.对象的浅拷贝与深拷贝 什么是对象的拷贝? 将一个对象赋值给另外一个对象, 我们称之为对象的拷贝 什么是深拷贝, 什么是浅拷贝? 我们假设将A对象赋值给B对象 浅拷贝是指, 修改B对象的属性和方法 ...

  6. javascript 动态加载javascript文件

    /* loadFile(data, callback): 动态加载js文件 data: 存放需要加载的js文件的url("url" || ["url", &qu ...

  7. 前端html,css考点

    1, 内联元素,块级元素相关知识点 参考链接:https://edu.aliyun.com/a/103378 (1)置换元素 概念:浏览器根据元素的标签和属性,来决定元素的具体显示内容.<img ...

  8. Nginx 核心配置

    nginx的核心配置在conf/nginx.conf中. 全局配置块 user root; #运行worker进程的账户,user   用户   [组],默认以nobody账户运行 worker_pr ...

  9. WebSocket以及socketIO的使用

    简介 WebSocket 使得客户端和服务器之间的数据交换变得更加简单,允许服务端主动向客户端推送数据.在 WebSocket API 中,浏览器和服务器只需要完成一次握手,两者之间就直接可以创建持久 ...

  10. dubbo初识

    1.什么是dubbo? dubbo 是一个分布式服务框架 是一个高性能的RPC框架 它提供了三大核心能力:面向接口的远程方法调用,智能容错和负载均衡,以及服务自动注册和发现. 谈到了分布式服务框架 那 ...