hdu 3966 树链分割第一3遍
真的不好意思说话。你写得越多,对风暴各种问题泄露,更离谱,有什么错有。。
。但是,仍然有一个。同时经过规范的编写清晰的代码。不能认为是理所当然。。。
树桩阵列版:
#include<cstdio>
#include<cstring>
#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<iostream>
#include<algorithm>
using namespace std;
const int M = 50100;
int son[M],top[M],father[M],dep[M],ti[M],siz[M];
int idx,tp,n;
struct {
int head;
}H[M];
struct {
int v,next;
}E[M];
void dfs_1(int u,int fa){
son[u] = 0;siz[u] = 1;father[u] = fa;dep[u] = dep[fa] + 1;
for(int i=H[u].head;i!=-1;i=E[i].next){
int v = E[i].v;
if(v == fa)continue;
dfs_1(v,u);
siz[u] += siz[v];
if(siz[son[u]] < siz[v])son[u] = v;
}
}
void dfs_2(int u,int fa){
top[u] = fa;
ti[u] = idx++;
if(son[u]) dfs_2(son[u],fa);
for(int i=H[u].head;i!=-1;i=E[i].next){
int v = E[i].v;
if(v == father[u]|| v == son[u])continue;
dfs_2(v,v);
}
}
int lobit(int x){
return x&(-x);
}
int num[M*2];
void update(int x ,int d){
while( x <= n){
num[x] += d;
x += lobit(x);
}
}
void change(int u,int v,int w){
int f1 = top[u];
int f2 = top[v];
while(f1 != f2){
if(dep[f1] <dep[f2]){
swap(f1,f2);
swap(u,v);
}
update(ti[f1],w);
update(ti[u]+1,-w);
u = father[f1];f1 = top[u];
}
if(dep[u] > dep[v])swap(u,v);
update(ti[u],w);
update(ti[v]+1,-w);
}
int sum(int x){
int ans = 0;
while(x>0){
ans += num[x];
x -= lobit(x);
}
return ans;
} void add(int u,int v){
E[tp].v = v;
E[tp].next = H[u].head;
H[u].head = tp++;
}
void init(){
memset(E,-1,sizeof(E));
memset(H,-1,sizeof(H));
memset(num,0,sizeof(num));
tp = 0;
idx = 1;
}
int findp(int x){
return sum(ti[x]);
}
int a[M];
int main(){
// freopen("input.txt","r",stdin);
int m,p,u,v,w;
while(scanf("%d%d%d",&n,&m,&p)==3){
init();
for(int i=1;i<=n;i++){
scanf("%d",&a[i]);
}
while(m -- ){
scanf("%d%d",&u,&v);
add(u,v);add(v,u);
}
dfs_1(1,1);
dfs_2(1,1);
for(int i=1;i<=n;i++){
update(ti[i],a[i]);
update(ti[i]+1,-a[i]);
} char op[100];
while (p--){
scanf("%s%d",op,&u);
if(op[0] == 'Q'){
printf("%d\n",sum(ti[u]));
}else {
scanf("%d%d",&v,&w);
if(op[0] == 'D')w = -w;
change(u,v,w);
}
} }
}<span style="background-color: rgb(255, 0, 0);">
</span>
线段树版:
#pragma comment(linker,"/STACK:100000000,100000000")
#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
#define lson id << 1
#define rson id << 1 | 1
const int M = 50010;
int a[M],top[M],ti[M],son[M],father[M],siz[M],dep[M];
int tp,idx;
struct {
int head;
}H[M*2];
struct {
int v,next;
}E[M*4];
void add(int u,int v){
E[tp].v = v;
E[tp].next = H[u].head;
H[u].head = tp++;
}
void dfs_1(int u,int fa){
son[u] = 0;siz[u] =1;dep[u] = dep[fa] + 1;father[u] = fa;
for(int i=H[u].head;i!=-1;i=E[i].next){
int v = E[i].v;
if(v == fa)continue;
dfs_1(v,u);
siz[u] += siz[v];
if(siz[v] > siz[son[u]])son[u] = v; }
}
void dfs_2(int u,int fa){
ti[u] = ++idx;top[u] = fa;
if(son[u])dfs_2(son[u],fa);
for(int i=H[u].head;i!=-1;i=E[i].next){
int v = E[i].v;
if(v == father[u]||v == son[u])continue;
dfs_2(v,v);
}
}
/* 线段树*/ struct Lintree{
int l,r,w,mark;
int mid(){
return (l+r) / 2;
}
}node[M*4];
void build_tree(int id,int l,int r){
node[id].l = l;
node[id].r = r;
node[id].mark = 0;
if(l == r)return; int mid = node[id].mid();
build_tree(lson,l,mid);
build_tree(rson,mid+1,r);
}
void push_down(int id){
if(node[id].mark){
node[lson].mark += node[id].mark;
node[rson].mark += node[id].mark;
node[id].mark = 0;
}
}
void update(int id,int l,int r,int w){
if(node[id].l == l && node[id].r == r){
// cout <<"dfasf -->" <<l<<"dfsf" <<r<<endl;
node[id].mark+=w;
return;
}
push_down(id);
int mid = node[id].mid();
if(r <=mid)update(lson,l,r,w);
else if(l > mid)update(rson,l,r,w);
else {
update(lson,l,mid,w);
update(rson,mid+1,r,w);
}
}
int query(int id,int x){
if(node[id].l == x&&node[id].r == x ){
// cout <<"<sdf>"<< node[id].w<<endl;
return node[id].mark;
}
push_down(id);
int mid = node[id].mid();
if(x <=mid)return query(lson,x);
else return query(rson,x);
}
void change(int u,int v,int x){
// cout <<u<<"**"<<v<<endl;
int f1 = top[u],f2 = top[v];
while(f1 != f2){
if(dep[f1] < dep[f2]){
swap(f1,f2);
swap(u,v);
}
update(1,ti[f1],ti[u],x);
u = father[f1];f1 = top[u];
}
//if(u == v)return
if(dep[u] > dep[v])swap(u,v);
update(1,ti[u],ti[v],x);
}
void init(){
memset(E,-1,sizeof(E));
memset(H,-1,sizeof(H));
tp = idx = 0;
}
int main(){
int n,m,p,u,v,w;
//freopen("input.txt","r",stdin);
while(~scanf("%d%d%d",&n,&m,&p)){
init(); for(int i=1;i<=n;i++)
scanf("%d",&a[i]);
while(m--) {
scanf("%d%d",&u,&v);
add(u,v);
add(v,u);
}
dfs_1(1,1);
dfs_2(1,1);
build_tree(1,1,n);
char op[1000]; while(p--){
scanf("%s",op);
if(op[0] == 'Q'){
scanf("%d",&u);
printf("%d\n",query(1,ti[u])+a[u]);
}else {
scanf("%d%d%d",&u,&v,&w);
if(op[0] == 'D') w = -w;
change(u,v,w); }
}
}
}
版权声明:本文博主原创文章。博客,未经同意不得转载。
hdu 3966 树链分割第一3遍的更多相关文章
- HDU 3966 (树链剖分+线段树)
Problem Aragorn's Story (HDU 3966) 题目大意 给定一颗树,有点权. 要求支持两种操作,将一条路径上的所有点权值增加或减少ai,询问某点的权值. 解题分析 树链剖分模板 ...
- hdu 3966(树链剖分+线段树区间更新)
传送门:Problem 3966 https://www.cnblogs.com/violet-acmer/p/9711441.html 学习资料: [1]线段树区间更新:https://blog.c ...
- HDU 3966 /// 树链剖分+树状数组
题意: http://acm.hdu.edu.cn/showproblem.php?pid=3966 给一棵树,并给定各个点权的值,然后有3种操作: I x y z : 把x到y的路径上的所有点权值加 ...
- hdu 3966 树链剖分
思路:树链剖分入门题,我这门入得好苦啊,程序很快写出来了,可是在LCA过程中把update函数里的左右边界位置写反了,一直RE到死. #pragma comment(linker, "/ST ...
- HDU 3966 树链剖分后线段树维护
题意: 一棵树, 操作1.$path(a,b)$之间的点权$+k$ 操作2.单点查询 题解: 树链剖分即可,注意代码细节,双向映射 主要是记录一下板子 #include <string.h> ...
- HDU - 3966 树链刨分
题目传送门 操作就是询问某个点的值, 然后就是对一条路径上的值全部修改. 最基本的树刨题目了. 树刨的思想: 1. 对于每个点找到他的重儿子. void dfs1(int o, int u){ sz[ ...
- HDU 3966 树链剖分+树状数组 模板
Aragorn's Story Time Limit: 10000/3000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) ...
- HDU 5274(树链剖分)
树链剖分第一题QAQ,纪念下 #pragma comment(linker, "/STACK:102400000,102400000") #include <iostream ...
- hdu 5893 (树链剖分+合并)
List wants to travel Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/O ...
随机推荐
- eclipse config 2 tab -> space
编码规范要求不同意使用tab,可是又要有4个字符的缩进,连点4次space,这不是程序猿的风格 来看看 eclipse 设置一次tab像space的转换 例如以下操作 Window->Prefe ...
- python3 序列
python中有很多内置序列 列表 元组 字符串 python中容器的概念 列表 元组 字符串 字典 集合 是可以改变的,元组不可改变 几乎可以在所有情况下用列表代替元组,只有一种情况下,是不可以的, ...
- 剪枝法观点下的旅行商问题(TSP)
1. 构建基本的穷举搜索骨架 int n; int dst[100][100]; int best; const int INF = 987654321; // 初始状态下,path 存入第一节点,v ...
- 【69.77%】【codeforces 723A】The New Year: Meeting Friends
time limit per test1 second memory limit per test256 megabytes inputstandard input outputstandard ou ...
- LIGO找到首个超越广义相对论的证据?
转自 麻省理工科技评论 原文 LIGO找到首个超越广义相对论的证据? 1915年,爱因斯坦根据简单的原理提出广义相对论,极大地改变了人们的时空观.广义相对论不仅解释了牛顿理论无法解释的现象,还做出许多 ...
- Bluetooth---初步了解Android 蓝牙4.0
http://developer.android.com/reference/android/bluetooth/package-summary.html android.bluttooth 提供管理 ...
- 在word中使用notepad++实现代码的语法高亮 分类: C_OHTERS 2013-09-22 10:38 2273人阅读 评论(0) 收藏
转载自:http://blog.csdn.net/woohello/article/details/7621651 有时写文档时需要将代码粘贴到word中,但直接粘贴到word中的代码虽能保持换行与缩 ...
- php课程 5-19 php数据结构函数和常用函数有哪些
php课程 5-19 php数据结构函数和常用函数有哪些 一.总结 一句话总结: 1.php数据结构函数有哪些(四个)? • array_pop();从最后弹出一个值,返回弹出值• array_pus ...
- 【9207&&b701】统计数字(NOIP2007)
问题描述 某次科研调查时得到了n个自然数,每个数均不超过1500000000 (1.5*109).已知不相同的数不超过10000个,现在需要统计这些自然数各自出现的次数,并按照自然数从小到大的顺序输出 ...
- html5 video标签如何禁止视频下载
html5 video标签如何禁止视频下载 一.总结 一句话总结:bing方法给video对象绑定return false的匿名方法. 1.html5 video标签如何禁止视频下载? bing方法给 ...