HDU 3966 Aragorn's Story (树链点权剖分,成段修改单点查询)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3966

树链剖分的模版,成段更新单点查询。熟悉线段树的成段更新的话就小case啦。

  1 //树链剖分 边权修改 单点查询
  2 #include <iostream>
  3 #include <cstring>
  4 #include <algorithm>
  5 #include <cstdio>
  6 using namespace std;
  7 const int MAXN = 5e4 + 10;
  8 struct data {
  9     int to , next;
 10 }edge[MAXN << 1];
 11 int head[MAXN] , cnt , tot;
 12 int top[MAXN] , par[MAXN] , son[MAXN] , size[MAXN] , dep[MAXN];
 13 int id[MAXN] , fid[MAXN]; //id[i]表示i对应在线段树上的位置 fid[i]表示线段树位置是i的叶子 对应的节点 
 14 int a[MAXN];
 15 
 16 void init() {
 17     tot = cnt = 0;
 18     memset(head , -1 , sizeof(head));
 19 }
 20 
 21 inline void add(int u , int v) {
 22     edge[tot].next = head[u];
 23     edge[tot].to = v;
 24     head[u] = tot++;
 25 }
 26 
 27 void dfs1(int u , int p , int d) {
 28     dep[u] = d , size[u] = 1 , son[u] = u , par[u] = p;
 29     for(int i = head[u] ; ~i ; i = edge[i].next) {
 30         int v = edge[i].to;
 31         if(v == p)
 32             continue;
 33         dfs1(v , u , d + 1);
 34         if(size[v] >= size[son[u]] || son[u] == u)
 35             son[u] = v;
 36         size[u] += size[v];
 37     }
 38 }
 39 
 40 void dfs2(int u , int p , int t) {
 41     top[u] = t , id[u] = ++cnt;
 42     fid[cnt] = u;
 43     if(son[u] != u)
 44         dfs2(son[u] , u , t);
 45     for(int i = head[u] ; ~i ; i = edge[i].next) {
 46         int v = edge[i].to;
 47         if(v == p || v == son[u])
 48             continue;
 49         dfs2(v , u , v);
 50     }
 51 }
 52 
 53 struct segtree {
 54     int l , r;
 55     int sum;
 56 }T[MAXN << 2];
 57 
 58 void pushup(int p) {
 59     if(T[p].sum != 0) {
 60         int ls = p << 1 , rs = (p << 1)|1;
 61         T[ls].sum += T[p].sum;
 62         T[rs].sum += T[p].sum;
 63         T[p].sum = 0;
 64     }
 65 }
 66 
 67 void build(int p , int l , int r) {
 68     int mid = (l + r) >> 1;
 69     T[p].l = l , T[p].r = r;
 70     T[p].sum = 0;
 71     if(l == r) {
 72         T[p].sum = a[fid[l]]; //
 73         return ;
 74     }
 75     build(p << 1 , l , mid);
 76     build((p << 1)|1 , mid + 1 , r);
 77 }
 78 
 79 void updata(int p , int l , int r , int num) {
 80     int mid = (T[p].l + T[p].r) >> 1;
 81     if(T[p].l == l && T[p].r == r) {
 82         T[p].sum += num;
 83         return ;
 84     }
 85     pushup(p);
 86     if(r <= mid) {
 87         updata(p << 1 , l , r , num);
 88     }
 89     else if(l > mid) {
 90         updata((p << 1)|1 , l , r , num);
 91     }
 92     else {
 93         updata(p << 1 , l , mid , num);
 94         updata((p << 1)|1 , mid + 1 , r , num);
 95     }
 96 }
 97 
 98 int query(int p , int pos) {
 99     int mid = (T[p].l + T[p].r) >> 1;
100     if(T[p].l == T[p].r && T[p].r == pos) {
101         return T[p].sum;
102     }
103     pushup(p);
104     if(pos <= mid) {
105         return query(p << 1 , pos);
106     }
107     else {
108         return query((p << 1)|1 , pos);
109     }
110 }
111 
112 void change(int u , int v , int num) {
113     int fu = top[u] , fv = top[v];
114     int sum = 0;
115     while(fu != fv) {
116         if(dep[fu] > dep[fv]) {
117             updata(1 , id[fu] , id[u] , num);
118             u = par[fu];
119             fu = top[u];
120         }
121         else {
122             updata(1 , id[fv] , id[v] , num);
123             v = par[fv];
124             fv = top[v];
125         }
126     }
127     if(dep[u] >= dep[v]) {
128         updata(1 , id[v] , id[u] , num);
129     }
130     else {
131         updata(1 , id[u] , id[v] , num);
132     }
133 }
134 
135 int main()
136 {
137     int n , u , v , m , xx;
138     while(~scanf("%d %d %d" , &n , &xx , &m)) {
139         init();
140         for(int i = 1 ; i <= n ; ++i) {
141             scanf("%d" , a + i);
142         }
143         for(int i = 1 ; i < n ; ++i) {
144             scanf("%d %d" , &u , &v);
145             add(u , v);
146             add(v , u);
147         }
148         cnt = 0;
149         dfs1(1 , 1 , 0);
150         dfs2(1 , 1 , 1);
151         build(1 , 1 , cnt);
152         char q[10];
153         while(m--) {
154             scanf("%s" , q);
155             if(q[0] == 'Q') {
156                 scanf("%d" , &xx);
157                 printf("%d\n" , query(1 , id[xx]));
158             }
159             else if(q[0] == 'I') {
160                 scanf("%d %d %d" , &u , &v , &xx);
161                 change(u , v , xx);
162             }
163             else {
164                 scanf("%d %d %d" , &u , &v , &xx);
165                 change(u , v , -xx);
166             }
167         }
168     }
169     return 0;
170 }

 

转载于:https://www.cnblogs.com/Recoder/p/5518179.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/257157.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

微信分享无响应的解决

微信分享无响应的解决 最近使用友盟的社会化分享&#xff0c;集成到程序中进行分享功能的开发。 可是一开始还是可以正常使用&#xff0c;今天突然发现微信分享&#xff08;好友分享和朋友圈分享&#xff09;均是点击没有响应&#xff0c;也就是点击后&#xff0c;没有任何回馈…

x64电脑连接x32共享打印机

下载64位打印机驱动到64位电脑&#xff0c;在连接32位共享打印机出错时出现在本地寻找相关inf文件&#xff0c;此时将64位打印机驱动解压(不在64位本地安装)并找到相应inf文件&#xff0c;载入即可连接成功。

HTML中的br标签讲解(菜鸟)

br标签&#xff1a;如何在HTML中换行&#xff1f;可以使用br标签 1.br标签作用&#xff1a;换行 2.br标签格式&#xff1a;<br/> 3.br标签的注意点&#xff1a; 3.1多个br标签可以连续使用&#xff0c;使用了多少个br标签就会换多少行 3.2由于HTML的作用就是用来给文本添…

Cocos2d-3.x版的HelloWorld工程分析 (二)

我们HelloWorld 从applicationDidFinishLaunching()后&#xff0c; 大部分人都会从这部分代码开始研究&#xff0c;如果想要研究main函数 如何调用applicationDidFinishLaunching() 传送门 http://blog.csdn.net/hiwoshixiaoyu/article/details/51472707 #include "App…

安卓中bundle的使用

Bundle类用作携带数据&#xff0c;它类似于Map&#xff0c;用于存放key-value形式的值&#xff0c;相对于Map&#xff0c;它提供了各种常用类型的putXxx()/getXxx()方法&#xff0c;Bundle的内部实际上是使用了HashMap类型的变量来存放PutXxx()方法存入的值。 SDK里是这样描述&…

NO.1 python_人工智能_学习路线

***##学习路线&#xff1a;* 1.python基础 计算机组成原理、python开发环境、python变量、流程控制语句、文件操作、异常处理、模块与包、飞机大战游戏制作等 2.python高级应用 网络编程、并发编程、数据库编程、正则表达式、Linux系统应用、函数的高级应用、python的语法进阶…

wds+mdt 分布式自动部署 操作系统

一、 安装准备 1、工具的准备 首先介绍本次项目所涉及到的内容&#xff1a; MDT Microsoft Deployment Toolkit 2012&#xff08;简称MDT 2012&#xff09;是微软最新一代部署工具&#xff0c;通过它可以自动完成桌面和服务器部署的推荐操作进程和工具&#xff0c;MDT主要…

iOS开发网络篇—数据缓存

iOS开发网络篇—数据缓存 一、关于同一个URL的多次请求 有时候&#xff0c;对同一个URL请求多次&#xff0c;返回的数据可能都是一样的&#xff0c;比如服务器上的某张图片&#xff0c;无论下载多少次&#xff0c;返回的数据都是一样的。 上面的情况会造成以下问题 &#xff08…

[WinError 10061] 由于目标计算机积极拒绝,无法连接错误解决办法

爬虫的时候会经常出现"[WinError 10061] 由于目标计算机积极拒绝&#xff0c;无法连接"错误这种情况&#xff0c;有可能是LAN口设置不正确 我是在爬取全国天气情况的时候出现的这种错误&#xff0c;后面调了以后可以了1.控制面板——网络和 Internet—— Internet选项…

Chrome浏览器设置小窗口视频

快捷工具先安装1.28版本后用1.31版本替换&#xff0c;以实现视频弹窗和双击关闭标签页功能。 首先下载Chrome扩展快捷工具1.28版的CRX安装包&#xff1a;http://pan.baidu.com/s/1pJ4T4td&#xff1b; 然后拖放到chrome扩展管理页面中安装。 接着&#xff0c;下载打包好的快捷…

这门课有什么用?

每个老师都苦恼于学生常问的问题&#xff1a;“某某课学了有什么用&#xff1f;”老师费劲巴拉解释一通&#xff0c;结果还是&#xff1a;然并卵。 一门课有什么用&#xff0c;很难解释得令人信服&#xff0c;因为这和人的认知水平有关。认知水平达不到&#xff0c;解释的多深入…

NO.1_python_scrapy组成爬取多页数据连接数据库配置文件书写

scrapy框架组成及各部分作用 item pipelines: 用于存放需要存储数据的数据模型&#xff0c;一般格式为&#xff1a; #需要存储多少中类型的数据就写多少行&#xff0c;一般是key_value组合 数据名称&#xff0c;即key scrapy.Field()spiders 用于解析返回来的response im…

“智云大咖秀”:大咖摄影师谈惊艳亮相的“大咖级”设备

古人云&#xff0c;善书者不择笔。 古人又云&#xff0c;工欲善其事必先利其器。 古人很矛盾。 这两句话如果用在影像创作这个领域&#xff0c;可以说都有道理&#xff1a;没有好的设备&#xff0c;创意大师一样能够拍出足够惊艳的作品&#xff1b;有足够强的设备&#xff0c;但…

英语 用on还是/at/还是in

in prep. 1. [表示地点、场所、位置等]在…里面&#xff1b;在…内部&#xff1b;在…上&#xff1a;例句: in the room 在房间里 2. [表示时间]在…期间&#xff1b;在(一段时间)以内&#xff1b;过…之久&#xff1a;例句: in summer 在夏天in 3. [表示状态]在…状态中&…

js编写简易返回顶部按钮

之前ui设计让我做个返回顶部的按钮,我一定头绪都没,感觉真要加上这个功能,自己编写就得一个下午,工作量大为由,所以就推脱了; 当静下心,有时间捣鼓之后才发现原来so easy!!! 以下是我的js代码,不足之处还请博友们批评指正; //原生js操作代码  function scrolls(){   v…

NO.2_python_scrapy_反爬虫(随机请求头IP代理)取消链接去重

1.随机请求头 # -*- coding: utf-8 -*- """ 所有请求头的USER_AGENTS网址 http://www.useragentstring.com/pages/useragentstring.php?nameAll """ import json import random import requestsUSER_AGENTS [Mozilla/5.0 (Windows NT 10.0; W…

Cobub无码埋点关键技术的实现

随着大数据时代的到来&#xff0c;数据采集也已经变的越来越重要。前端埋点作为一个比较成熟的数据接入手段被广泛应用着。目前埋点分为两种方式&#xff0c;有码与无码埋点。有码埋点比较容易理解&#xff0c;即调用SDK的API&#xff0c;在代码中插入埋点的相关代码&#xff0…

Dedesql数据库类详解(二次开发必备教程)(转)

http://www.dedecms.com/help/development/2009/1028/1076.html 织梦DedeCMS的二次开发不仅仅是会写写织梦的标签&#xff0c;会制作织梦的模板。很多时候&#xff0c;我们需要对织梦DedeCMS的数据库进行查询、插入、删除等等之类的操作&#xff0c;进行这一类的操作之前&#…

装系统换固态硬盘方法

1、将买回的固态硬盘直接换上电脑的原先机械硬盘 2、或者将自己的光驱拆卸&#xff0c;将固态硬盘装上去 3、电脑进入boss 界面&#xff0c;找到boot(引导)栏&#xff0c;找到自己的u盘&#xff0c;进入后先分区&#xff0c;然后再重启&#xff0c; 然后再进入BOSS进入U盘里&…

学习笔记(02):Python网络编程并发编程-assert断言的用途

立即学习:https://edu.csdn.net/course/play/24458/296228?utm_sourceblogtoedu 异常处理 1.异常的捕捉 try:正常需要运行的代码except 可能出现的错误 as e:出现这种错误需要运行的代码...except Exception as e:捕捉未知的错误&#xff0c;并且将需要运行的代码放于此处el…