数据结构习题 线段树&树状数组
说明:这是去年写了一半的东西,一直存在草稿箱里,今天整理东西的时候才发现,还是把它发表出来吧。。
以下所有题目来自Lrj的《训练指南》
LA 2191
单点修改,区间和 Fenwick直接搞
UVa 12299
给出n个数,支持循环移动某些数(<30个),然后问区间最小值
因为移动小于30个数,所以直接单点修改就行,线段树。
LA 4108
类似线段树,每次插入一个建筑时想线段树一样二分区间,当遇到一个完整的区间时,修改或返回,否则继续二分区间。Nlogn.
UVa 11525
有题解说可以逆向考虑用线段树,我没明白怎么回事。
说一下我的做法:
考虑问题(k,n)表示1~k的全排列中第n个。显然1~k的全排列可以分为k种,每种有(k-1)!种情况,那么如果确定了第n个排列属于哪一种,问题就转化为了(k-1,m);
再考虑题目的输入。N的输入形式正好是按以上思想给出的,那么我们是需要把这个式子转化为标准形式即可。
判断每个Si,若Si>(k-i+1),就要”进位”。所以从后向前扫描,可以在O(n)时间内解决。
LA 4730
并查集+线段树。用并查集维护每个州,同时维护每个州的上端点(up)和下端点(down)。
用线段树维护[a,b]内有多少个城市。方法是连接A和B时,[A.down,A.up]-=A.count; [B.down,B.up]-=B.count; [new.down,new.up]+=new.count;
二维线段树
先存一下(以下代码仅供参考 准确性无法保证233)
#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <cstring>
#define RS(x) (x*2+1)
#define LS(x) (x*2)
#define bigger(a,b) ((a)>(b)?(a):(b))
#define minner(a,b) ((a)<(b)?(a):(b))
#define MAXN (2000+10)
#define root (1)
#define INF (9999999)
using namespace std;
struct Segment_Tree_2D{
struct treeY{
int max,min;
int L,R;
int mid;
};
typedef struct treeY treeY;
struct treeX{
treeY T[MAXN];
int L,R;
int mid;
};
typedef struct treeX treeX;
int x1,x2,y1,y2,val,max_ans,min_ans,x0,y0;
treeX t[MAXN];
void queryY(int f,int r,int fa,int p){//ok
if (r>t[fa].T[p].R) r=t[fa].T[p].R;
if (f<t[fa].T[p].L) f=t[fa].T[p].L;
if (f==t[fa].T[p].L&&r==t[fa].T[p].R){
max_ans=bigger(max_ans,t[fa].T[p].max);
min_ans=minner(min_ans,t[fa].T[p].min);
}else{
int mid=t[fa].T[p].mid;
if (r>mid) queryY(mid+,r,fa,RS(p));
if (f<=mid) queryY(f,mid,fa,LS(p));
}
}
void queryX(int f,int r,int p){//ok
if (r>t[p].R) r=t[p].R;
if (f<t[p].L) f=t[p].L;
if (f==t[p].L&&r==t[p].R){
queryY(y1,y2,p,root);
}else{
int mid=t[p].mid;
if (r>mid) queryX(mid+,r,RS(p));
if (f<=mid) queryX(f,mid,LS(p));
}
}
void modifyY(int fa,int p){//ok
if (y0==t[fa].T[p].L&&y0==t[fa].T[p].R){
t[fa].T[p].min=val;
t[fa].T[p].max=val;
}else{
int mid=t[fa].T[p].mid;
if (y0>mid) modifyY(fa,RS(p));
if (y0<=mid) modifyY(fa,LS(p));
}
t[fa].T[p].max=bigger(t[fa].T[LS(p)].max,t[fa].T[RS(p)].max);
t[fa].T[p].min=minner(t[fa].T[LS(p)].min,t[fa].T[RS(p)].min);
}
void maintainY(int fa,int p){//ok
if (y0==t[fa].T[p].L&&y0==t[fa].T[p].R){
t[fa].T[p].min=minner(t[LS(fa)].T[p].min,t[RS(fa)].T[p].min);
t[fa].T[p].max=bigger(t[LS(fa)].T[p].max,t[RS(fa)].T[p].max);
}else{
int mid=t[fa].T[p].mid;
if (y0>mid) maintainY(fa,RS(p));
if (y0<=mid) maintainY(fa,LS(p));
}
t[fa].T[p].max=bigger(t[fa].T[LS(p)].max,t[fa].T[RS(p)].max);
t[fa].T[p].min=minner(t[fa].T[LS(p)].min,t[fa].T[RS(p)].min);
}
void modifyX(int p){
if (x0==t[p].L&&x0==t[p].R){
modifyY(p,root);
}else{
int mid=t[p].mid;
if (x0>mid) modifyX(RS(p));
if (x0<=mid) modifyX(LS(p));
maintainY(p,root);
}
} void query(){max_ans=-INF;min_ans=INF;queryX(x1,x2,root);}
void modify(){modifyX(root);}
};
typedef struct Segment_Tree_2D ST2;
ST2 t;
int main()
{
int i,j,n,m,temp,q;
char cmd[];
scanf("%d%d",&n,&m);
for (i=;i<=n;i++){
for (j=;j<=m;j++){
scanf("%d",&temp);
t.x0=i; t.y0=j;
t.modify();
}
}
scanf("%d",&q);
for (i=;i<q;i++){
scanf("%s",cmd);
if (cmd[]=='q'){
scanf("%d%d%d%d",&t.x1,&t.y1,&t.x2,&t.y2);
t.query();
printf("%d %d\n",t.max_ans,t.min_ans);
}else{
scanf("%d%d",&t.x0,&t.y0);
t.modify();
}
}
return ;
}
数据结构习题 线段树&树状数组的更多相关文章
- CodeForces -163E :e-Government (AC自动机+DFS序+树状数组)
The best programmers of Embezzland compete to develop a part of the project called "e-Governmen ...
- NOIp 数据结构专题总结 (2):分块、树状数组、线段树
系列索引: NOIp 数据结构专题总结 (1) NOIp 数据结构专题总结 (2) 分块 阅:<「分块」数列分块入门 1-9 by hzwer> 树状数组 Binary Indexed T ...
- 数据结构--树状数组&&线段树--基本操作
随笔目的:方便以后对树状数组(BIT)以及基本线段树的回顾 例题链接:http://acm.hdu.edu.cn/showproblem.php?pid=1166 例题:hdu 1166 敌兵布阵 T ...
- HDU 1556 线段树或树状数组,插段求点
1.HDU 1556 Color the ball 区间更新,单点查询 2.题意:n个气球,每次给(a,b)区间的气球涂一次色,问最后每个气球各涂了几次. (1)树状数组 总结:树状数组是一个查 ...
- tyvj P1716 - 上帝造题的七分钟 二维树状数组区间查询及修改 二维线段树
P1716 - 上帝造题的七分钟 From Riatre Normal (OI)总时限:50s 内存限制:128MB 代码长度限制:64KB 背景 Background 裸体就意味着 ...
- hdu 4836 The Query on the Tree(线段树or树状数组)
The Query on the Tree Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Ot ...
- 【BZOJ3295】动态逆序对(线段树,树状数组)
[BZOJ3295]动态逆序对(线段树,树状数组) 题面 Description 对于序列A,它的逆序对数定义为满足iAj的数对(i,j)的个数.给1到n的一个排列,按照某种顺序依次删除m个元素,你的 ...
- ZJOI 2017 树状数组(线段树套线段树)
题意 http://uoj.ac/problem/291 思路 不难发现,九条カレン醬所写的树状数组,在查询区间 \([1,r]\) 的时候,其实在查询后缀 \([r,n]\) :在查询 \([l,r ...
- 「CodePlus 2017 11 月赛」Yazid 的新生舞会(树状数组/线段树)
学习了新姿势..(一直看不懂大爷的代码卡了好久T T 首先数字范围那么小可以考虑枚举众数来计算答案,设当前枚举到$x$,$s_i$为前$i$个数中$x$的出现次数,则满足$2*s_r-r > 2 ...
随机推荐
- 启发式搜索技术A*
开篇 这篇文章介绍找最短路径的一种算法,它的字我比较喜欢:启发式搜索. 对于入门的好文章不多,而这篇文章就是为初学者而写的,很适合入门的一篇.文章定位:非专业性A*文章,很适合入门. 有图有真相,先给 ...
- 【BZOJ4817】[Sdoi2017]树点涂色 LCT+线段树
[BZOJ4817][Sdoi2017]树点涂色 Description Bob有一棵n个点的有根树,其中1号点是根节点.Bob在每个点上涂了颜色,并且每个点上的颜色不同.定义一条路径的权值是:这条路 ...
- Olya and Energy Drinks(bfs)
D. Olya and Energy Drinks time limit per test 2 seconds memory limit per test 256 megabytes input st ...
- 160819、JavaScript-数组去重由慢到快由繁到简
JavaScript-数组去重由慢到快由繁到简演化 indexOf去重 Array.prototype.unique1 = function() { var arr = []; for (var ...
- Git中如何将代码恢复到之前某个节点
本文主要讲如何使用小乌龟软件将代码恢复到之前某个节点. 一 说明 在实际项目开发中,都是很多人一起联合开发,往往会遇到这种情况:马上要发版本了,突然发现一个致命BUG,而这个BUG是由于某个小伙伴修改 ...
- [NOIP2018TG]赛道修建
[NOIP2018TG]赛道修建 考场上multiset调不出啊啊啊!!! 首先肯定是二分答案 做树形dp,f[i]表示i点的子树两两匹配后剩下的最长长度 匹配可以用multiset维护 但是菊花图跑 ...
- 如何修改本地hosts文件?
1.window7修改本地hosts文件 # window7系统hosts文件位置 C:\Windows\System32\drivers\etc 2.linux # linux系统hosts文件位置 ...
- Android系统移植与调试之------->增加一个双击物理按键打开和关闭闪光灯并将闪光灯状态同步到下拉菜单中
最近有一个客户有这样的需求: 1.在[设置]--->[无障碍]中添加一个开关按钮. 如果打开开关的话,双击某个物理按键的时候,打开闪光灯,再双击该物理按键的时候,关闭闪光灯. 如果关闭开关的话, ...
- windows下 安装python_ldap MySQL-python
//////////////////////////////////////////////////// 失败 ---------------------------------------- F ...
- Java基础—运算符(转载)
转载自:Java运算符 计算机的最基本用途之一就是执行数学运算,作为一门计算机语言,Java也提供了一套丰富的运算符来操纵变量.我们可以把运算符分成以下几组: 算术运算符 关系运算符 位运算符 逻辑运 ...