bzoj 3052 树上莫队 待修改
感谢:
http://vfleaking.blog.163.com/blog/static/174807634201311011201627/
http://hzwer.com/5250.html
好吧,收获两点:
1、带修改,其实就是暴力,只是将同一块的查询再按照时间顺序排,这样就能减少在修改操作上“爬"的时间,其实就是利用了数据随机这个特点,可以构造数据来卡。
2、以前排序的方法是u按照块,v按照dfs序,这次两个都是按照块,其实差不多。
/**************************************************************
Problem: 3052
User: idy002
Language: C++
Result: Accepted
Time:101223 ms
Memory:21792 kb
****************************************************************/ #include <cstdio>
#include <cmath>
#include <vector>
#include <algorithm>
#define P(p) ((1)<<(p))
#define maxn 100010
#define maxp 16
using namespace std; typedef long long dint; int n, m, q, qq, qm;
int cc[maxn], ww[maxn], vv[maxn];
vector<int> g[maxn], stk;
int mno[maxn], mcc_siz, mcc_cnt;
int anc[maxn][maxp+], depth[maxn], dfn[maxn], dfs_clock;
bool stat[maxn];
dint cnt[maxn], cur_ans;
dint ans[maxn];
int mdu[maxn], mdc[maxn], mdo[maxn], mdcc[maxn]; struct Qu {
int u, v, t, id;
bool operator<( const Qu & b ) const {
if( mno[u]^mno[b.u] ) return mno[u]<mno[b.u];
if( mno[v]^mno[b.v] ) return mno[v]<mno[b.v];
return t<b.t;
}
};
Qu qu[maxn]; int dfs( int u ) {
dfn[u] = ++dfs_clock;
depth[u] = depth[anc[u][]]+;
for( int p=; p<=maxp; p++ ) {
anc[u][p] = anc[anc[u][p-]][p-];
if( !anc[u][p] ) break;
} int sz = ;
for( int t=; t<g[u].size(); t++ ) {
int v = g[u][t];
if( v==anc[u][] ) continue;
anc[v][] = u;
sz += dfs(v);
if( sz > mcc_siz ) {
mcc_cnt++;
for( int i=; i<=sz; i++ ) {
mno[stk.back()] = mcc_cnt;
stk.pop_back();
}
sz = ;
}
}
stk.push_back( u );
return sz+;
} int lca( int u, int v ) {
if( depth[u]<depth[v] ) swap(u,v);
int t = depth[u]-depth[v];
for( int p=; t; t>>=, p++ )
if( t& ) u=anc[u][p];
if( u==v ) return u;
for( int p=maxp; p>= && anc[u][]!=anc[v][]; p-- )
if( anc[u][p]!=anc[v][p] )
u = anc[u][p], v = anc[v][p];
return anc[u][];
} void inv_sig( int u ) {
if( stat[u] ) {
cur_ans -= (dint)ww[cnt[cc[u]]]*vv[cc[u]];
cnt[cc[u]]--;
} else {
cnt[cc[u]]++;
cur_ans += (dint)ww[cnt[cc[u]]]*vv[cc[u]];
}
stat[u] ^= ;
} void chg_sig( int u, int type ) {
if( stat[u] ) {
inv_sig(u);
cc[u] = type;
inv_sig(u);
} else cc[u] = type;
} void inv_chain( int u, int v ) {
int ca = lca(u,v);
for( ; u!=ca; u=anc[u][] ) inv_sig(u);
for( ; v!=ca; v=anc[v][] ) inv_sig(v);
}
void app_time( int fm, int to ) {
while( fm<to ) {
fm++;
chg_sig(mdu[fm],mdc[fm]);
}
while( to<fm ) {
chg_sig(mdu[fm],mdo[fm]);
fm--;
}
} void work() {
sort( qu+, qu++qq );
int ou=qu[].u;
int ov=qu[].u;
int ot=;
for( int i=; i<=qq; i++ ) {
int u = qu[i].u, v = qu[i].v;
inv_chain( u, ou );
inv_chain( v, ov );
app_time( ot, qu[i].t );
ot = qu[i].t;
ou = u;
ov = v;
int ca = lca(u,v);
inv_sig( ca );
ans[qu[i].id] = cur_ans;
inv_sig( ca );
}
} int main() {
scanf( "%d%d%d", &n, &m, &q );
for( int i=; i<=m; i++ ) scanf( "%d", vv+i );
for( int i=; i<=n; i++ ) scanf( "%d", ww+i );
for( int i=,u,v; i<n; i++ ) {
scanf( "%d%d", &u, &v );
g[u].push_back(v);
g[v].push_back(u);
}
mcc_siz = (int)(pow(n,2.0/3.0))+;
dfs();
while( !stk.empty() ) {
mno[stk.back()] = mcc_cnt;
stk.pop_back();
}
for( int i=; i<=n; i++ ) {
scanf( "%d", cc+i );
mdcc[i] = cc[i];
}
for( int i=,type,x,y; i<=q; i++ ) {
scanf( "%d%d%d", &type, &x, &y );
if( !type ) {
qm++;
mdu[qm]=x, mdc[qm]=y, mdo[qm]=mdcc[x];
mdcc[x] = y;
} else {
qq++;
qu[qq].u=x, qu[qq].v=y, qu[qq].t=qm, qu[qq].id=qq;
}
}
work();
for( int i=; i<=qq; i++ )
printf( "%lld\n", ans[i] );
}
bzoj 3052 树上莫队 待修改的更多相关文章
- BZOJ.3052.[WC2013]糖果公园(树上莫队 带修改莫队)
题目链接 BZOJ 当然哪都能交(都比在BZOJ交好),比如UOJ #58 //67376kb 27280ms //树上莫队+带修改莫队 模板题 #include <cmath> #inc ...
- P4074 [WC2013]糖果公园 树上莫队带修改
题目链接 Candyland 有一座糖果公园,公园里不仅有美丽的风景.好玩的游乐项目,还有许多免费糖果的发放点,这引来了许多贪吃的小朋友来糖果公园游玩. 糖果公园的结构十分奇特,它由 nn 个游览点构 ...
- uoj #58. 【WC2013】糖果公园(树上莫队算法+修改操作)
[题目链接] http://uoj.ac/problem/58 [题意] 有一棵树,结点有自己的颜色,若干询问:u,v路径上的获益,并提供修改颜色的操作. 其中获益定义为Vc*W1+Vc*W2+…+V ...
- bzoj 3757 树上莫队
感谢以下文章作者: http://blog.csdn.net/kuribohg/article/details/41458639 http://vfleaking.blog.163.com/blog/ ...
- BZOJ - 3757 树上莫队解决离线路径问题 & 学习心得
题意:给你一棵树,求u,v最短路径的XXX(本题是统计权值种类) 今天课上摸鱼学了一种有意思的处理路径方式(其实是链式块状树翻车了看别的),据说实际运行跑的比XX记者还快 大概就是像序列莫队那样 首先 ...
- 【bzoj3052】[wc2013]糖果公园 带修改树上莫队
题目描述 给出一棵n个点的树,每个点有一个点权,点权范围为1~m.支持两种操作:(1)修改一个点的点权 (2)对于一条路径,求$\sum\limits_{i=1}^m\sum\limits_{j=1} ...
- [BZOJ 3052] [wc2013] 糖果公园 【树上莫队】
题目链接:BZOJ - 3052 题目分析 这道题就是非常经典的树上莫队了,并且是带修改的莫队. 带修改的莫队:将询问按照 左端点所在的块编号为第一关键字,右端点所在的块为第二关键字,位于第几次修改之 ...
- BZOJ 4129: Haruna’s Breakfast [树上莫队 分块]
传送门 题意: 单点修改,求一条链的mex 分块维护权值,$O(1)$修改$O(S)$求mex...... 带修改树上莫队 #include <iostream> #include < ...
- 【bzoj4129】Haruna’s Breakfast 带修改树上莫队+分块
题目描述 给出一棵树,点有点权.支持两种操作:修改一个点的点权,查询链上mex. 输入 第一行包括两个整数n,m,代表树上的结点数(标号为1~n)和操作数.第二行包括n个整数a1...an,代表每个结 ...
随机推荐
- Django之kindeditor
1.什么是kindeditor? KindEditor是一套开源的HTML可视化编辑器,主要用于让用户在网站上获得所见即所得编辑效果,兼容IE.Firefox.Chrome.Safari.Opera等 ...
- Tensorflow常用函数说明(一)
首先最开始应该清楚一个知识,最外面的那个[ [ [ ]]]括号代表第一维,对应维度数字0,第二个对应1,多维时最后一个对应数字-1:因为后面有用到 1 矩阵变换 tf.shape(Tensor) 返回 ...
- Codeforces Round #466
A. Points on the line 题意 给定一条直线上\(n\)个点,要求去掉最少的点,使得直线上相距最远的两个点的距离\(\leq d\). 思路 枚举长度为\(d\)的区间. Code ...
- Balanced and stabilized quicksort method
The improved Quicksort method of the present invention utilizes two pointers initialized at opposite ...
- Redis使用详细教程【转】
转自 Redis使用详细教程 - wangyuyu - 博客园http://www.cnblogs.com/wangyuyu/p/3786236.html 一.Redis基础部分: 1.redis介绍 ...
- MYSQL三种安装方式--rpm包安装
1. 首先检查机器里是否已经存在MySQL $ rpm -qa | grep mysql 2. 去官网下载相应的rpm包:https://dev.mysql.com/downloads/mysql/ ...
- python基础(12)--初识Socket
socket: 网络上的两个程序通过一个双向的通信连接实现数据的交换,这个连接的一端称为一个socket. Socket的英文原义是“孔”或“插座”.作为BSD UNIX的进程通信机制,取后一种意思. ...
- Linux下突然不识别无线网卡
昨天还能用wifi的Linux,今天进去后发现没有了wifi的图标,ifconfig也不显示无线网卡.怎么办? 出现这种情况,肯定是上次关机之前做了一些操作导致的.我遇到过的一个情况是:Fedora2 ...
- (转载)Linux入门:操作目录和文件的命令
PATH 每个用户的PATH都是不一样的: PATH中不包含“当前目录”: (1)echo $PATH:显示PATH环境变量: (2)PATH = "$PATH":/home/ ...
- bzoj 1856 卡特兰数
复习了一下卡特兰数.. #include<bits/stdc++.h> #define LL long long #define fi first #define se second #d ...