
-------------数据结构-------------
Lynstery
一只蒟蒻
展开
-
[二进制分组 + 凸包] BZOJ4140: 共点圆加强版
对于给出的一个圆心 (xi,yi)(xi,yi)(x_i,y_i) ,在它内部点 (x,y)(x,y)(x,y) 需满足 (x−xi)2+(y−yi)2≤x2i+y2i⇔x2+y2≤2xxi+2yyi⇔yi≥−xyxi+x2+y22y(x−xi)2+(y−yi)2≤xi2+yi2⇔x2+y2≤2xxi+2yyi⇔yi≥−xyxi+x2+y22y(x-x_i)^2+(y-y_i)^2 \le x...原创 2018-02-11 23:47:36 · 459 阅读 · 0 评论 -
[线段树+哈希] Codeforces 452F. Permutation
要注意到这是一个排列,1~n每个数都出现一次,不用上这个条件就做不了。对于一个数 xx , 所有的x−k, x+kx-k,\ x+k 一定在 xx 的同一侧,否则就输出YESYES 。所以就有了这样的解法:从左到右扫描序列,设当前到ii , 已经把 11 到 i−1i-1 的数都丢到权值线段树中了。若此时x−k, x+kx-k,\ x+k 有一个是1,有一个是0,则说明找到了。也就是只要比较一下权值原创 2017-10-06 15:01:04 · 340 阅读 · 0 评论 -
[Hall定理 + 线段树] LibreOJ#6062. 「2017 山东一轮集训 Day2」Pair
可以先对 BB 排序,然后 AA 中的每个数能匹配的 BB 中的元素都是一个后缀的形式。 对于一个 AA 元素的集合是否与 BB 有完美匹配呢? 可以考虑Hall定理,随便选一个B中的集合S: 由于图的特殊性,N(S)=N(S中从下标最小的元素开始的后缀)N(S)=N(S中从下标最小的元素开始的后缀) ,也就是说只要所有后缀都满足 N(S)≥|S|N(S)\ge |S|,则任意集合都满足。 这原创 2017-10-10 21:46:51 · 1047 阅读 · 0 评论 -
[链表] BZOJ1098: [POI2007]办公楼biu
太菜了…这都不会… 就是求反图的联通块。就是每次挑一个边在反图bfs出一个块。 我们每次找反图边扩展,是找原图中和当前节点不直接相连的其他点。直接暴力会变成 n2n^2 所以需要把访问过的点马上删去。可以用链表。 这样每个点就只访问一次了。复杂度 O(n+m)O(n+m)#include<cstdio>#include<queue>#include<cstring>#include<a原创 2017-09-29 11:00:07 · 377 阅读 · 0 评论 -
[主席树] BZOJ1112: [POI2008]砖块Klo
水题。直接主席树求区间中位数,然后中位数左边右边求sum和cnt。算一下就好了。#include<cstdio>#include<algorithm>#define mp(x,y) make_pair(x,y)#define Fir first#define Sec secondusing namespace std;typedef long long LL;const int max原创 2017-09-29 09:59:01 · 389 阅读 · 0 评论 -
[均摊复杂度线段树] Codeforces #438D. The Child and Sequence
水~~~#include<cstdio>#include<algorithm>using namespace std;const int maxn=200005;typedef unsigned long long uLL; struct node{ node* ch[2]; uLL sum,_max; node(uLL t1=0,uLL t2=0,node原创 2017-09-28 11:33:50 · 333 阅读 · 0 评论 -
[离线+树状数组] HDU5869 Different GCD Subarray Query
对于这种询问有多少个不同的东西,有比较套路的方法是把询问离线,然后同种元素的贡献记在最近的位置上。比如 BZOJ1878 [SDOI2009]HH的项链 这题也是类似的做法,只是一个点上的元素不是1个而是log V个。所以就 O(nlog2n)O(nlog^2n)#include<cstdio>#include<cstring>#include<vector>#include<algorit原创 2017-09-19 18:13:29 · 459 阅读 · 0 评论 -
[贪心] BZOJ2006: [NOI2010]超级钢琴
经典题。 超级钢琴模型。取前k个最优的问题,总状态太多时,尽量根据显然的优劣关系,减少当前待选最优值,用堆搞,取了一个之后放出后续可能有用的。#include<cstdio>#include<queue>#include<cmath>#include<algorithm>#define Fir first#define Sec secondusing namespace std;con原创 2017-09-19 18:07:09 · 416 阅读 · 0 评论 -
[主席树+哈希] Codechef June Challenge 2017 #CLONEME
主席树+哈希套路。通过哈希做到快速比较一些东西是否相等,很可能和字典序什么的有关。这题就是利用哈希,在主席树上二分一样地走,找到从左边开始第一个不一样的和从右边开始第一个不一样的,然后xjb判断一下就好了。#include<cstdio>#include<algorithm>#define Lh ch[0]->hsh#define Rh ch[1]->hsh#define Ls ch[0]-原创 2017-09-19 17:50:27 · 413 阅读 · 0 评论 -
[线段树] BZOJ2957: 楼房重建
经典题,线段树维护上升序列。#include<cstdio>#include<algorithm>#include<cstring>#define Max(p) p->_max#define lenL(p) p->lenL#define lenR(p) p->lenRusing namespace std;inline char gc(){ static char buf[10原创 2017-09-25 21:19:48 · 311 阅读 · 0 评论 -
[线段树] CodeChef Count on a Treap
要求两点距离,只需做到能求两点 lcalca 和任意一点的深度即可。 Treap其实是一棵笛卡尔树,构造过程就是对于 keykey 递增的序列,每次选 ww 最大的作为根,然后两边分为左右子树递归。 那么x,y的 lcalca 实际上就是 [x,y][x,y] 中 ww 最大的,比较显然。 然后就是怎么求深度,考虑一个节点 xx 的父亲,它一定是序列中离 xx 最近的且 ww 大于 w(x)原创 2017-09-25 20:48:33 · 324 阅读 · 0 评论 -
[扫描线 + 线段树] 51Nod1672 区间交
这题数列都是非负的,所以就比较简单了。 可以扫描线,枚举左端点,然后考虑覆盖了左端点的区间,挑右端点第 KK 大就好了。#include<cstdio>#include<vector>#include<algorithm>#include<cstring>#define Fir first#define Sec second#define mp(x,y) make_pair(x,y)原创 2017-10-20 20:46:22 · 323 阅读 · 0 评论 -
[杂题 树状数组] 51Nod1681 公共祖先
不错的题,思路很套路。考虑求的答案是 ∑i,j∑k[k在两棵树中都是i,j的祖先]\sum_{i,j} \sum_k [k在两棵树中都是i,j的祖先] 改变枚举顺序,设 Son1(x)Son_1(x) 表示第一棵树中以x为根的子树的点集,答案就变成: ∑k(|Son1(k)∩Son2(k)|2)\sum_k { | Son_1(k) \cap Son_2(k) |\choose 2} 这个原创 2017-10-30 07:47:34 · 379 阅读 · 0 评论 -
[dsu on tree] Codeforces #741D. Arpa's letter-marked tree and Mehrdad's Dokhtar-kosh paths
考虑一个字符集,若能排成回文串,则出现个数是奇数的字符种数是0或1。字符有22种,就想到异或。 合法的链 (x,y)(x,y) 满足 s(x) xor s(y)=0或2is(x)\text{ xor }s(y)=0或2^{i}。 直接 dsu on tree 瞎搞。 #include<cstdio>#include<vector>#include<algorithm>using names原创 2017-12-07 21:18:56 · 546 阅读 · 0 评论 -
[dsu on tree] Codeforces #600E. Lomsat gelral
所谓dsu on tree,就是树上的启发式合并,处理出重儿子然后搞就行了。树的特殊性会使写起来比数据结构启发式合并方便一点。只需维护一个数据结构,支持插入删除单个元素。 这题就是模板题啦…#include<cstdio>#include<vector>#include<algorithm>using namespace std;typedef long long LL;const in原创 2017-12-05 20:26:41 · 314 阅读 · 0 评论 -
[树链剖分+李超线段树] BZOJ4515: [Sdoi2016]游戏
先进行转化,把路径分成两条链,a(deps−depi)+b=(−a)∗depi+a∗deps+ba(dep_s-dep_i)+b=(-a)*dep_i+a*dep_s+b…类似这样变形一下,就转化成和 k∗depi+bk*dep_i+b 的形式。depidep_i 是递增的,所以可以看做是一次函数 y=kx+by=kx+b 在某些离散的点上有定义。 现在需要实现区间插入线段,求区间最小值。这个问题原创 2017-12-02 06:19:04 · 423 阅读 · 0 评论 -
[冒泡 反序表] Codeforces #876D. Sorting the Coins
冒泡需要的趟数 == 反序表最大值。 这题只有01两种数字,所以每次求最后的0前面有几个1就好了。 具体实现倒着搞比较好。#include<cstdio>#include<algorithm>using namespace std;const int maxn=300005;int n,bit[maxn],_max,a[maxn],ans[maxn];void Updata(int x原创 2017-10-17 09:52:01 · 417 阅读 · 0 评论 -
[two-pointer ST表] HDU5289: Assignment
这种什么对于所有区间,最大值最小值的问题,我们一般考虑求控制区间,或者分治。 分治一般都可做,按套路搞就行了。但可能不是太方便。 这题就很简单了,就考虑对于一个固定的右端点,合法左端点的区间。 很显然最小左端点位置是单调的,直接ST表预处理出区间最值,two pointertwo\ pointer 扫一扫就好了。#include<cstdio>#include<cmath>#include原创 2017-11-02 15:03:19 · 320 阅读 · 0 评论 -
[栈 二分图染色] NOIP2008 双栈排序
一道远古时期的联赛题,比较经典。 由于联赛快到了,这里就写一写有理有据的思考过程: 首先,这种题目应该手玩几次。我们想让字典序最小,肯定尽量往 S1S1 放。而什么时候需要用第二个栈呢?所以我们考虑当只有一个栈时,什么情况下不能排序。自己试一试之后,发现只有这种情况: 存在 i<j<k, ak<ai<aj,i<j<k,\ a_k<a_i<a_j, 。这种情况下,因为后面有 kk 要先出来,导致原创 2017-10-16 15:24:50 · 340 阅读 · 0 评论 -
[杂题 异或 带权并查集] BZOJ2303: [Apio2011]方格染色
不太容易想到。首先要把限制看成异或,即每个点都要满足 ai,j xor ai,j−1 xor ai−1,j xor ai−1,j−1=1a_{i,j}\text{ xor }a_{i,j-1}\text{ xor }a_{i-1,j}\text{ xor }a_{i-1,j-1}=1 这些限制太复杂了,怎么进行转化呢? 注意到,如果我们已经确定的第一行和第一列的所有元素,则其他也确定了。所以原创 2017-10-31 14:16:39 · 436 阅读 · 0 评论 -
[枚举 线段树] 51Nod1494 选举拉票
直接做不太可做,我们可以枚举一个 dd 表示其他人最大值不大于 dd 时的方案数。 这样就好做多了,比 dd 大的部分就一定要全部扣掉。然后如果自己的票数不足 dd ,就需要在剩下的所有票里取最便宜的前几个,需要线段树询问前k小值的加和。#include<cstdio>#include<vector>#include<algorithm>#define Fir first#define Se原创 2017-10-24 07:54:53 · 504 阅读 · 0 评论 -
[杂题 离散 扫描线] BZOJ1227: [SDOI2009]虔诚的墓主人
不难的题。 考虑一个空的点的贡献是一个组合数的形式,即答案为 ∑(leftK)(rightK)(upK)(downK) \sum {left \choose K }{right \choose K }{up \choose K }{down \choose K } 怎么求呢? 显然先离散,只需考虑离散后的网格上的点。 对于每一行,可以考虑扫过取求两个实点中间空点的贡献,每一段的贡献是(le原创 2017-10-30 18:43:59 · 335 阅读 · 0 评论 -
[杂题 暴力 ST表] 51Nod1487 占领资源
这种题看似很暴力,但也不能太暴力,需要一定的思考。 我们先枚举一个塔,再考虑下一个塔,注意到第2个塔与第一个塔有重叠的只有最多 K2K^2 个,即暴力枚举交在哪里,直接就得到了。 对于这些有重叠的暴力算答案,剩下的都和第一个塔没有重叠,就挑一个最大值即可。 除去 K2K^2 个元素的最大值,不要用什么线段树单点修改,直接 STST 表预处理,跳过 除掉的元素,一段一段询问最大值即可。#incl原创 2017-10-21 21:43:08 · 338 阅读 · 0 评论 -
[栈] brackets 括号序列
这是一道傻逼题,就是有 ()[]()[] 两种括号的一个序列,求最长合法括号序列子段。n≤105n \le 10^5 以前在cf上做过类似的,我好像是分治搞的……真是学傻了…..所以在这里记一下。 实际上用栈搞一下就好了,我们知道一个合法括号序列插入栈之后就为空了,子段也一样。不断插入时统计答案。#include<cstdio>#include<cstring>#include<algori原创 2017-09-23 22:13:07 · 438 阅读 · 0 评论 -
[主席树] Codechef: Prefix XOR
题意给你 nn 个数,每个数的值是 aiai ,定义数对 (i,j)(i,j) 是上升的当且仅当: ai≤ai xor ai+1≤ai xor ai+1 xor ai+2≤⋯≤ai xor ai+1 xor ai+2⋯xor aja_i\le a_i ~\text{xor}~a_{i+1}\le a_i ~\text{xor}~a_{i+1} ~\text{xor}~a_{i+2}\le \cd原创 2017-08-02 00:31:35 · 457 阅读 · 0 评论 -
[莫比乌斯反演+数状数组] BZOJ3529: [Sdoi2014]数表
题意有一张N×m的数表,其第i行第j列(1 <=i <=n,1 <=j <=m)的数值为 能同时整除i和j的所有自然数之和。给定a,计算数表中不大于a的数之和。 多次询问,输入的第一行一个整数Q表示测试点内的数据组数,接下来Q行,每行三个整数n,m,a(|a| < =10^9)描述一组数据。 n,m,Q <=10^5 题解设g(i)为gcd(x,y)等于i的数对个数(x<=n,y<=m),原创 2017-07-03 11:49:04 · 413 阅读 · 2 评论 -
[LCT] BZOJ2002: [Hnoi2010]Bounce 弹飞绵羊
题意一条直线摆上n个装置,每个装置有个弹力系数ki,当绵羊达到第i个装置时,它会往后弹到第i+ki个装置,若不存在第i+ki个装置,则绵羊被弹飞。 绵羊想知道当它从第i个装置起步时,被弹几次后会被弹飞。 你需要执行m次操作,有两种类型: 1.修改某装置的弹力系数(ki始终为正整数) 2.询问从i起步被弹几次后会被弹飞 n,m<=200000题解算是LCT模板题吧。 添加一个点表示“弹飞”原创 2017-02-24 10:28:34 · 563 阅读 · 0 评论 -
主席树——模板整理
函数式线段树。 利用了可持久化的思想,降低时间和空间复杂度。#include<cstdio>#include<cstring>#include<algorithm>using namespace std;const int maxn=2000005;int n,Q,a[maxn],b[maxn];struct node{ int L,R,sum; node* ch[2]原创 2017-02-23 13:32:11 · 507 阅读 · 0 评论 -
[主席树+二分] BZOJ2653: middle
题意**给定一个数字序列。 多次询问,每次求出左端点为a~b,右端点为c~d的所有子序列的中位数的最大值。 一个序列的中位数: 一个长度为n的序列a,设其排过序之后为b,其中位数定义为b[n/2],其中a,b从0开始标号,除法取下整。**题解**很强的主席树应用。 可以想到二分答案,如何验证呢? 肯定算一下比当前答案mid大的数的个数和小的数的个数差。我们设大于等于mid的数为1,小于mi原创 2017-02-23 12:59:21 · 765 阅读 · 0 评论 -
树链剖分——模板整理
可解决在给定的树上的路径问题。 复杂度:O(log2nlog_2n)#include<cstdio>#include<cstring>#include<algorithm>using namespace std;const int maxn=100015, maxe=200015;int n,Q,fir[maxn],nxt[maxe],son[maxe],w[maxe],tot;int原创 2017-02-21 19:53:29 · 506 阅读 · 0 评论 -
splay维护序列——模板整理
时间复杂度O(log2nlog_2n)#include<cstdio>#include<cstring>#include<algorithm>using namespace std;struct node{ int key,size; node *ch[2]; void maintain(){ size=ch[0]->size+ch[1]->size+1; }原创 2017-02-21 19:46:45 · 628 阅读 · 0 评论 -
Treap——模板
基于旋转的Treap。 复杂度O(log2nlog_2n)#include<cstdio>#include<cstdlib>int max(int x,int y){ return x>y?x:y; }int min(int x,int y){ return x<y?x:y; }struct node{ node* ch[2]; int key,fix,size,cnt;原创 2017-02-21 19:42:56 · 438 阅读 · 0 评论 -
LCT ——学习笔记
终于会LCT了。我原本splay只会写刘汝佳的递归版本,用它写LCT各种烦。。。然后还是去学了一下非递归的。。。 LCT的思想有点类似树链剖分,即把边分为实边和虚边两类。树链剖分是用于静态问题的,没有边的插入删除,而LCT是动态树,显然两者实边和虚边具体定义不同。 LCT的实/虚边是不断变化的,和树链剖分类似,连成一条链的实边路径用splay维护其中的信息。splay序列按点的深度的顺序的,我们原创 2017-02-17 10:04:02 · 2271 阅读 · 0 评论 -
[动态点分治] BZOJ1095: [ZJOI2007]Hide 捉迷藏
题意给定N个节点的一棵树,一开始所有点都是黑色。需要执行Q个操作,操作有两种类型: 1.改变单点的颜色(黑变白,白变黑)。 2.询问最远黑色点对的距离。 N ≤100000, M ≤500000题解动态点分治经典题,一般和树上路径有关的题目都需要往这方面考虑。 对于每个点分树,我们把信息都收集到根节点上。 对于过某个根节点的路径,要求最长的一条:先对根节点的每个直接儿子求出以这个儿子为根的原创 2017-02-15 11:00:03 · 776 阅读 · 1 评论 -
[整体二分] BZOJ3110: [Zjoi2013]K大数查询
题意N个位置,M个操作。操作有两种: 1.在第a个位置到第b个位置,每个位置加入一个数c。注意是加入,也就是说这里的一个位置能放下多个数。 2.询问从第a个位置到第b个位置 的所有数中,第K大的数是多少。题解经典的整体二分题。 把所有操作排成一个序列,并二分答案mid。把当前操作序列中的所有插入的数大于mid的插入都执行一遍区间+1,对于每次询问即可求一次区间和得到比mid大的数有几个,原创 2017-02-12 10:34:26 · 530 阅读 · 0 评论 -
[树链剖分] BZOJ1036: [ZJOI2008]树的统计Count
题意给出一棵树,单调修改点权,询问路径点权和与点权最大值。解析树链剖分模板题,线段树只需要支持单点修改+区间询问即可。#include<cstdio>#include<algorithm>using namespace std;const int maxn=30005,maxe=60005;int n,Q,w[maxn],fir[maxn],nxt[maxe],son[maxe],tot;原创 2017-02-11 21:54:12 · 442 阅读 · 0 评论 -
[平衡树+启发式合并 || 点分治] POJ1741 Tree
题意这题就是楼教主男人必做八题之一 给出一棵有边权的树,以及一个数K,求距离小于等于K的点对的个数。题解点分治显然可做,对于当前点分树,把所有点到当前根的距离排序后扫一下即可。 复杂度O(nlog22n)O(nlog^2_2n)。 这里主要讲一下另一种不错的思路——平衡树+启发式合并。 具体做法: 随便找个根,然后递归下去从叶到根把子树不断合并。过程中,给每个子树建平衡树来存其中所有点到子树原创 2017-02-27 20:41:51 · 810 阅读 · 1 评论 -
[Splay] BZOJ1500: [NOI2005]维修数列
题意题解纯数据结构题,用来练代码能力很不错。 就是用splay来维护这个序列,各种标记放上去,维护各种信息即可。 我们需要维护这些: val:节点的数字 size:子树大小 sum:子树对应的区间的数字和 ml:子树对应区间的最大前缀和(长度>0) mr:子树对应区间的最大后缀和(长度>0) allm:子树对应区间的最大连续子段和(长度>0) rev:翻转标记 same:修改标记原创 2017-02-28 19:52:38 · 517 阅读 · 0 评论 -
[动态MST] [CDQ分治] BZOJ2001: [Hnoi2010]City 城市建设
题意PS国是一个拥有诸多城市的大国,国王Louis为城市的交通建设可谓绞尽脑汁。Louis可以在某些城市之间修建道路,在不同的城市之间修建道路需要不同的花费。Louis希望建造最少的道路使得国内所有的城市连通。但是由于某些因素,城市之间修建道路需要的花费会随着时间而改变,Louis会不断得到某道路的修建代价改变的消息,他希望每得到一条消息后能立即知道使城市连通的最小花费总和, Louis决定求助于你原创 2017-07-11 22:53:40 · 568 阅读 · 0 评论 -
[均摊 线段树] UOJ#228. 基础数据结构练习题
题意题解先膜一下九老师 %%% 可以先感性理解一下,不断进行区间开根号操作,整个序列会不断“趋近于一致“。比如说: 3123 42 5 --> 55 6 2 --> 7 2 1 --> 2 1 1 --> 1 1 1 就算数字之间相差很大,搞几下就很接近了。 由于有区间加操作,所以可以想到从相邻数的差进行考虑。 区间加操作体现到差分数组上只是两个点的改变。 所以就有这样一种想法,不断的原创 2017-05-20 19:43:54 · 642 阅读 · 0 评论