Poj 4047 Garden /2012金华邀请赛D题(线段树)

ai-hedge-fund(Python) 「ai-hedge-fund(Python)」是开源项目(Python)。项目简介:An AI Hedge Fund Team源码完整,下载解压即可查看使用,适合学习参考、课程设计与二次开发。 立即下载

题意:给出长度为200000的数列,进行200000次下列操作:

0 x y 将x的值置为y

1 x y 交换x和y的值

2 x y 求[x,y]区间内和最大的一个连续的长度为k的区间(y-x>k)

解法:显而易见的线段树开始一直想维护每个区间的最大k区间,但是一直想不出怎么维护父节点和子节点的关系。估计如果实在现场会困死在此题。。。

       于是需要转换一下思维,把点当做区间把区间当做一个点,具体来说,线段树上每个叶子节点i的值为数列i~i+k-1的和,这样求[x,y]的最大值就转换成了求[x,y-k+1]区间的最大值,对于每次对于点的更新,更新它能影响到的所有长为k的区间,即 [x - k + 1,x];这种思想经常用到,比如前几天碰到的一道alibaba校园赛费用流问题(hdu4106)

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.StreamTokenizer;
public class Garden {
	class SegTree {
		class node {
			int left, right;
			int max, add;
			int mid() {
				return (left + right) >> 1;
			}
		}
		node tree[]=new node[600010];
		void init(int left, int right, int idx, int a[]) {
			tree[idx] = new node();
			tree[idx].left = left;
			tree[idx].right = right;
			if (left == right) {
				tree[idx].max = a[left];
				return;
			}
			int mid = tree[idx].mid();
			init(left, mid, idx << 1, a);
			init(mid + 1, right, (idx << 1) | 1, a);
			tree[idx].max = Math.max(tree[idx << 1].max,
					tree[(idx << 1) | 1].max);
		}

		void pushdown(int idx) {
			if (tree[idx].add == 0)
				return;
			int k = tree[idx].add;
			tree[idx].max += k;
			tree[idx].add = 0;
			if (tree[idx].left == tree[idx].right)
				return;
			tree[idx << 1].add += k;
			tree[(idx << 1) | 1].add += k;
		}

		void update(int left, int right, int idx, int v) {
			pushdown(idx);
			if (left <= tree[idx].left && right >= tree[idx].right) {
				tree[idx].add += v;
				return;
			}
			int mid = tree[idx].mid();
			if (left <= mid)
				update(left, right, idx << 1, v);
			if (right > mid)
				update(left, right, (idx << 1)|1, v);
			pushdown(idx<<1);
			pushdown((idx<<1)|1);
			tree[idx].max = Math.max(tree[idx << 1].max,
					tree[(idx << 1)|1].max);
		}

		int query(int left, int right, int idx) {
			pushdown(idx);
			if (tree[idx].left == left && tree[idx].right == right) {
				return tree[idx].max;
			}
			int mid = tree[idx].mid();
			if (right <= mid)
				return query(left, right, idx << 1);
			else if (left > mid)
				return query(left, right, (idx << 1) | 1);
			else
				return Math.max(query(left, mid, idx << 1),
						query(mid + 1, right, (idx << 1) | 1));
		}
	}

	SegTree st = new SegTree();
	int sum[]=new int[200010], arr[]=new int[200010], p[]=new int[200010];
	StreamTokenizer in = new StreamTokenizer(new BufferedReader(
			new InputStreamReader(System.in)));

	int next() throws IOException {
		in.nextToken();
		return (int) in.nval;
	}

	void run() throws IOException {
		int cas = next();
		while (cas-- > 0) {
			int n = next();
			int m = next();
			int k = next();
			for (int i = 1; i <= n; i++) {
				p[i] = next();
				sum[i] = p[i] + sum[i - 1];
			}
			for (int i = 1; i + k - 1 <= n; i++)
				arr[i] = sum[i + k - 1] - sum[i - 1];
			st.init(1, n - k + 1, 1, arr);
			while (m-- > 0) {
				int op =next();
				int x = next();
				int y = next();
				if (op == 0) {
					int from = x - k + 1;
					if (from < 1)
						from = 1;
					int key = y - p[x];
					p[x] = y;
					st.update(from, x, 1, key);
				}
				if (op == 1) {
                    int from=x-k+1;
                    if(from<1)
                    	from=1;
                    int temp=p[x];
                    int key=p[y]-p[x];
                    p[x]=p[y];
                    st.update(from, x, 1, key);
                    from=y-k+1;
                    if(from<1)
                    	from=1;
                    key=temp-p[y];
                    p[y]=temp;
                    st.update(from, y, 1, key);
				}
				if(op==2)
				{
					int to=y-k+1;
					System.out.println(st.query(x, to, 1));
				}
			}
		}
	}
	public static void main(String[] args) throws IOException {
		new Garden().run();
	}
}

PS:再次感慨线段树的变化多端,虽然种过二三十颗树了还是驾驭不了,这几天继续种。。。


园区管委会如何有效推进智能制造转型,提升企业竞争力?.docx 科易网基于40亿+科创知识图谱数据库,深度探索AI技术在技术转移、成果转化、技术经纪、知识产权、产业创新、科技招商等垂直领域的多样化应用场景,研究科技创新领域的AI+数智化解决方案,推动科技创新与产业创新智能化发展。 立即下载

相关推荐

实用流程图软件Diagram Designer中文版

源码直接下载地址: https://pan.quark.cn/s/426802cc3918 流程图是编程人员整理思路所必需的工具。无论是初学者还是经验丰富的开发者,都离不开它。该流程图支持多语言版本,其中包含中文,用户可以自行进行设置。Diagram Designer设计器是一个基础的矢量图形流程图、图表以及幻灯片编辑工具。它提供了可定制的对象模板(额外的模板可以下载),能够利用大量的数学表达式来绘制基本的图形,同时支持多页面以及多层次的图表,可以导入其他图形格式并具备更多的功能支持。Diagram Designer允许用户创建多种图表样式,涵盖流程图、网络地图、应用程序接口、电子电路以及其他广泛的图形类型。Diagram Designer作为一个矢量图像编辑工具,用于构建流程图、图表和滑动展览。它包含一个可定制的样板和调色板,以及简易的图形绘制功能。支持使用压缩的文件格式。它是一个操作简便的矢量图编辑器,可用于绘制流程图、UML图、说明图以及演示文稿。

2012金华邀请赛报告

这次的没学过的算法多了起来,虽然我都猜对了是用什么算法(我只知道大体上各算法的原理,但没写过。。)。。还有翻译上的严重失误。这次太惨了。。。差点挂零。。 这次比赛的pdf地址:http://poj.org/ProblemDescriptions/jinghua.pdf A题目地址:POJ 4044 由于上次我在低端上的失误。。已被队友嫌弃。。。已经被剥夺写签到的权利。。。但是这

scf0920 1286

FFmpeg魔改指南:让RTMP协议完美兼容H265的三种方法(含SRS适配技巧)

本文详细介绍了三种让RTMP协议兼容H265编码的FFmpeg魔改方案,包括基于官方补丁的标准改造、Intel的SVT-HEVC集成方案以及金山云的自定义扩展方案。文章重点解析了各方案的实现原理与适配技巧,并提供了在SRS 6.0服务器上进行深度配置和性能调优的完整实战指南,帮助开发者解决H265推流至传统RTMP服务器的兼容性问

weixin_29290947的博客 167

2012金华邀请赛D(POJ4047 Garden)报告

金华邀请赛D,现场lazy标记推错了,颇为不爽,重做一下。 给出一个N个数的序列以及一个k(0<k<=n<=200000),m个操作p,x,y,其中 p=0:将x位置的数替换为y p=1:将x y位置的数互换 p=2: 查询x-y位置区间连续k个数的和的最大值 很快可以想到用O(n)的复杂度预处理,将从i位置起始连续k个数的和求出来,那么对于查询操作,就变...

258

hdu 4419 Colourful Rectangle(矩形面积并)

意:给出红绿蓝三种颜色的矩形,某些元素重叠之后会组合成其它颜色,问7种颜色的面积分别为多少。 解法:考虑只有两种颜色AB,那么求A颜色矩形的面积并x,B颜色矩形的面积并为y,AB颜色矩形的面积并为z,则最终,AB颜色的面积为x+y-z,A颜色的面积为x-(x+y-z),B颜色的面积为y-(x+y-z); 类似得,考虑三种颜色: 根据公式先求出三种颜色混和的面积x,然后依次只考虑两种

新博客地址:sensirly.github.io 2479

spoj 861 SWAPS & uva 11990 "Dynamic'' Inversion(动态维护逆序对)

意:有150000个数,10000条操作,每次将第i个数变为x,讯问每次操作后逆序对的数目。 解法1:树状数组+treap,树状数组的每个元素都是一棵树,这样可以在lognlogn时间内查询前i项有多少个小于等于k的元素,当某个元素法师改变时,只需从树状数组中对应的treap中进行元素的删减,每次修改前后统计的第i个元素形成的逆序对数,便可知每次操作后逆序对的数目。由于Treap常熟很

新博客地址:sensirly.github.io 2257

hdu 4391 Paint The Wall(根N分段哈希)

将整个区间分为sqrt(n)段小区间,每个段长度为sqrt(n),并维护每一段的统计量,这样可以在sqrt(n)时间内完成一次区间查询或更新。平衡查询和更新之间矛盾是数据结构设计时的重要考虑因素,而这种做法是经典的平衡做法,早就了解,但以前没有遇到过只能用“分段”解决的题目,因此总觉着这是迫不得已的“赖招”,也从来没有写过,昨天第一次写,小细节没注意,结果悲剧的写成每次查询O(n)了。总结一下错误

新博客地址:sensirly.github.io 1655

扫描线算法在线段树中的应用

可能是没怎么搞计算几何的知识,至今对扫描线算法没有很清晰的认识,记得当初ZY大神是这样定义的:              每一个事件有一个开始时间和结束时间,将所有时间点排序,然后依次扫描,如果是开始时间就将时间加入,否则就将事件删除。则可以在任意时刻处理当前发生的事件。 扫描线在计算几何中使用相对多一些,我只是为了刷通线段树的列表粗略了了解了一下,只可就事论事,无法统筹全局。“矩形面积并”是

新博客地址:sensirly.github.io 1322

fzu 2045 \ hdu 3973 AC's String线段树+RK)

意:给出10000个模式串和一个长度为100000的匹配串,有两种操作: 1.查询匹配串的子串[L,R]是否存在于模式串中 2.修改匹配串某个位置的字符 解法:由于RK函数满足区间加法啊,因此可以用线段树动态维护和查询某个子串的hash值,得到子串的hash值,剩下的就是普通的rk了。 将所有模式串的hash值放入map中,对于hash值相同的模式串使用链表串联起来,当获取某个子串的

新博客地址:sensirly.github.io 1319

并查集专辑

并查集大体分为三个:普通的并查集,带种类的并查集,扩展的并查集(主要是必须指定合并时的父子关系,或者统计一些数据,比如此集合内的元素数目。) 一篇不错的科普文http://hi.baidu.com/czyuan%5Facm/blog/item/531c07afdc7d6fc57cd92ab1.html 普通并查集: 几道裸体大水: poj 1611The Suspects记录并查集中元

新博客地址:sensirly.github.io 1156

hdu 4358 Boring counting

意:给出一棵树,每个点有一个点权,问一x为根的子树中有多少种权重恰好出现了k次。 懒了,直接贴解,况且本来也不是自己写出来的 #include #include #include #include #include using namespace std; const int maxn = 100010; struct node { int be, ne; void

新博客地址:sensirly.github.io 1102

CF(173E) Camping Groups

题目链接 意:一个俱乐部有 n名成员,每名成员有两个属性:声望r和年纪a(均为109)。若干个个可以组成一个小组,每个小组中有一名组长,要求这名组长的声望高于其他成员且这名组长与组内任意成员的年龄差小于k,先给出10000条查询,问如果a、b两人在一个小组中,那么这个小组最多可以有多少人。 解法:1.由于n和a相差很大,因此首先要对声望和年纪进行离散化           2.每个小组

新博客地址:sensirly.github.io 926

树状数组专辑

树状数组是一个优美小巧的数据结构,在很多时候可以代替线段树。树状数组的本质就是一种通过二进制位来维护一个序列前i和的数据结构。(详见论文或http://old.blog.edu.cn/user3/Newpoo/archives/2007/1712628.shtml) 树状数组按照维数分为1维和2维,按照类型分可以分为插点问段和插段问点,这两个互逆,只是改变for循环的方向就可以了。一

新博客地址:sensirly.github.io 917

poj 3467 Cross Counting

意:给出一个M*N 的矩阵,矩阵中每个元素都有一种颜色(1 ≤ N, M, C ≤ 100),10000条查询,更改某个元素的颜色或查询某种颜色的corss有多少个。 We say there exists a cross of size k centered at the cell (x,y)iff all cells lying in the x-th row or the y

新博客地址:sensirly.github.io 875

hdu 4262 Juggler(树状数组)

意:某人手上有一串珠子,顺时针编号1--n,每次可进行三种操作:顺时针旋转一个珠子,逆时针旋转一个珠子,将手中的珠子移去(移去后顺时针方向下一个珠子进入手中),问按标号12345顺序将所有珠子逐一移去,最少需要多少次操作。 分析:假设当前要移除的珠子为x,x左边的珠子用A代表,右边的珠子用B代表即AxB,则无论左移还是右移都会得到xBA,即移去某个珠子对后面的珠子无影响,每次只需单独考虑A和B

新博客地址:sensirly.github.io 851

SPOJ/GSS3:Can you answer these queries III(线段树)

http://www.spoj.pl/problems/GSS3/ 意:给出一个数列,求某个区间内的最大子序列和,并进行对某些点的更新。GSS1是个不更新只查询的简化版题目,差别不大。 跟hdu3397有点像,统计量也很像,但是犯了经验主义的错误,左起最大字段和=左区间左起最大字段和  或   左区间和+右区间左起最大字段和(如果左区间左起最大字段和==左区间和)是错误的,例如:100 -1

新博客地址:sensirly.github.io 842

POJ2892地道战Tunnel Warfare(线段树)

点击打开题目链接对连续的村庄进行三种操作和问询 D x: The x-th village was destroyed.Q x: The Army commands requested the number of villages that x-th village was directly or indirectly connected with including itself.R:

新博客地址:sensirly.github.io 839

poj 2843 Cutting Cake

意:一块N*N大的蛋糕M次讯问,每次切走一个矩形,问每次切的矩形被分成了多少块(1 解法:显然是求某个区域内的连通分量数目,由于这个区域内的元素在访问后会被切除,因此每个元素只被访问一次,因此可以通过dfs或bfs求得某个区域内的连通分量的个数,均摊复杂度。 但是每次寻找遍历的起始点(即区域内未被切走的蛋糕)复杂度为O(N^2),因此需要优化,最坏情况是怎么产生的呢?当某个区域内有连续的已

新博客地址:sensirly.github.io 804
上一篇: 树形DP入门
下一篇: 排列组合&区间计数
kksleric
博客等级 码龄16年 49粉丝 75原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值