随笔分类 - 数据结构
摘要:题意:给出n个塔和m堵墙,求出被围墙包围的区域有多少个。分析:并查集判断环的个数。View Code #include <cstdio>#include <cstring>int f[1001];int find(int x){ return f[x] == x?x:(f[x]=find(f[x]));}int main(){ int n, m; int i, j; int res = 0; while (scanf("%d %d",&n,&m)!=EOF) { res = 0; for (i=0; i<n; i++) ...
        阅读全文
            
摘要:题意:Give you three sequences of numbers A, B, C, then we give you a number X. Now you need to calculate if you can find the three numbers Ai, Bj, Ck, which satisfy the formula Ai+Bj+Ck = X.即给出一个A数组,B数组,C数组,和S个询问,每个询问给出一个X值,问是否存在符合条件的等式。分析:可以用hash存下a数组和b数组中所有元素的和,然后可以用hash或者二分的方法查找是否存在x-ck即可。View Code
        阅读全文
            
摘要:题意:问一个1..n 的排列中,有多少组数满足 i < j < k 且 num[i] < num[k] < num[j].分析:符合条件的答案即为 小大中的情况总数,而 小大中 = 小XX - 小中大 可以求出每个数前面小于它的数的个数x,和后面大于它的个数y, 那么每个数对应的 小XX 数量为 y*(y-1)/2 每个数对应的小大中数量为 x*y#include <stdio.h>#include <string.h>#define mod 100000007long long a[100005];int n;int lowbit(int x)
        阅读全文
            
摘要:题意: 知道了一颗有 n 个节点的树和树上每条边的权值,对应两种操作: 0 x 输出当前节点到 x节点的最短距离,并移动到 x 节点位置 1 x val 把第 x 条边的权值改为 val分析: 树上两个节点a,b的距离可以转化为 dis[a] + dis[b] - 2*dis[lca(a,b)] 其中 dis[i] 表示 i 节点到根的距离, 由于每次修改一条边,树中在这条边下方的 dis[] 值全都会受到影响,这样每条边都对应这一段这条边的管辖区, 可以深搜保存遍历该点的时间戳,ll[i] 表示第一次遍历到该点的时间戳, rr[i] 表示回溯到该点时的时间戳,这样每次 修改边 i 的时候就可
        阅读全文
            
摘要:题意: 知道了n 个连续位置处砖块的高度,有m个如下询问 l r h :区间[l,r] 中高度小于等于h的砖块有多少个。分析: 用树状数组离线处理砖块的高度,对砖块按高度从低到高排序,对询问按 h 从低到高排序,因为高度较小的砖块 不会影响跳 跃高度较大时候的答案,所以可以依次加入砖块,求出每个区间 的数目。#include<stdio.h>#include<string.h>#include<algorithm>using namespace std;#define clr(x)memset(x,0,sizeof(x))#define maxn 10000
        阅读全文
            
摘要:题意: 给出一颗有 n 个节点的树,问u 和 v 的最近公共祖先。分析: rmq:对树先进行深搜,记录深搜序列和每个序列的深度,将最近公共祖先的询问转化为区间最值问题。 tarjan:保存所有询问,在深搜的时候同时保存答案。rmq_在线算法#include<stdio.h>#include<string.h>#include<math.h>#define clr(x)memset(x,0,sizeof(x))#define maxn 10005struct node{ int to,next;}e[100000];int tot;int head[maxn]
        阅读全文
            
摘要:题意: 知道了一段序列的值,有m 个询问,输出询问区间内不同数字的和。分析:可以用离线的方法记录所有的询问,并按每个询问右区间的值排序,然后逐个插入数值,如果某个数值之前出现过,就将之前那个位置上的那个 数删除,并在新的位置上插入数值,如果当前插入数值的序号等于某个询问的右区间,就统计该询问区间的不同数值的值,由于数值比较大,需 要进行离散化,离散化可以用 hash 或 二分,将每个值映射到一个较小的数值上,以便用数组标记。#include<stdio.h>#include<string.h>#include<stdlib.h>#include<alg
        阅读全文
            
摘要:题意: 知道了连续的 n 个数的 值,有两种操作: 1 a b kc: adding c to each of Ai which satisfies a <= i <= b and (i - a) % k == 0 2 a :means querying the value of a分析:因为k比价小,可以多个树状数组,根据 i%k的不同建立k 个树状数组,每次修改操作对其中 1 棵树状数组进行操作 每次查询对其中10个树状数组统计结果累加。#include<stdio.h>#include<string.h>#define clr(x)memset(x,0
        阅读全文
            
摘要:题意: 找到线段上一点,使得其他单位到这一点的代价和最小。分析: 裸的三分。#include<stdio.h>#include<string.h>#include<stdlib.h>double ab(double x){ return x>0?x:-x;}struct node{ double x; double w;}q[50005];int n;double cal(double xi){ int i; double res=0; for(i=0;i<n;i++) { double t=ab(q[i].x-xi); r...
        阅读全文
            
摘要:题意: 有n 个城市,一开始每个城市有一颗龙珠,有 m 个操作 T a b 将a城市的所有龙珠转移到 b 城市 Q a 输出a龙珠所在的城市,和该城市现有的龙珠的数量,和该龙珠被转移的次数分析: 并查集,x 的祖先f[x]记录x 所在城市,每次合并的时候更新路径上的点#include<stdio.h>#include<string.h>#define maxn 10011int city[maxn];int move[maxn];int f[maxn];int find(int x){ if(f[x]==x) return x; int t=f[x]; ...
        阅读全文
            
摘要:题意: 有N件商品,知道了商品的价值和销售的最后期限,只要在最后日期之前销售处,就能得到相应的利润,并且销售该商品需要1天时间,求出最大利润。分析:利用并查集按利润排序,建立一个关于时间的并查集 每次插入一个物品时,若该物品时间为 i,找出find(i),记为t,若t不为0,则将该物品安排到t这个时间完成,并使f[t]=t-1 亦即对于每个物品尽量 安排在后边完成,安排后将fa指针前移,表示这个时间已经被占用,下次需要插入到它之前。#include<stdio.h>#include<string.h>#include<algorithm>#define cl
        阅读全文
            
摘要:题意: 给出一连串的表达式,需要求出他们的结果,并且需要判断这些结果能否首尾相连成一个串,如果可以输出字典最小的那个串。分析:表达式求解需要定义符号的优先级,并用栈来维护运算符和数值结果, 结果求出来后,可以对所有串按字典序排列,然后深搜找欧拉路径,第一次找到的即为字典序最小的那个。#include<stdio.h>#include<string.h>#include<stdlib.h>#define clr(x)memset(x,0,sizeof(x))int res[1005][3];struct node{ int f,l; char s[33];}q
        阅读全文
            
摘要:题意: 给出 n 个人,知道了每个人的成绩,和每个人想要的奖学金,要求从这些学生中找出 m (奇数)个人满足选出的人的成绩的中位数最大,且这些人总的奖学金需求要 小于等于总的奖学金数。分析: 可以先对学生按成绩降序排序,然后从位置m/2+1 到 N - m/2枚举,中位数 q[i],因此对于枚举每个中位数只要求出左面最小的 m/2个数,和右面最小的 m/2 个 数,只要 left[i-1]+q[i].money+rght[i+1] <=F ,i 即为要找的学生。 left[i] 表示从 i 个位置向左的序列中最小的 m/2个数之和,对于每次出现新的 i 值,要求出 m/2 个最小的数这个
        阅读全文
            
摘要:题意: 从小到大排序分析:堆排序讲解:View Code “堆”定义 n个关键字序列Kl,K2,…,Kn称为(Heap),当且仅当该序列满足如下性质(简称为堆性质): (1)ki<=k(2i)且ki<=k(2i+1)(1≤i≤ n),当然,这是小根堆,大根堆则换成>=号。//k(i)相当于二叉树的非叶结点,K(2i)则是左孩子,k(2i+1)是右孩子 若将此序列所存储的向量R[1..n]看做是一棵完全二叉树的存储结构,则堆实质上是满足如下性质的完全二叉树: 树中任一非叶结点的关键字均不大于(或不小于)其左右孩子(若存在)结点的关键字。 大根堆和小根堆:根结点(亦称为堆顶)的关
        阅读全文
            
摘要:题意: 有 N 个人分属于两个帮派,对应两种操作: A X Y 询问x,y 是否属于一个帮派,或两者关系不能确定。 D X Y X和Y 分属不同帮派分析: 感觉就是简化版的食物链...方法一: 加一个数组 r[i] r[i] = 0 表示 i 与祖先属于同一个帮派 r[i] = 1 表示 i 与祖先属于不同帮派View Code #include<stdio.h>#include<string.h>int f[100005];int r[100005];int find(int x){ int s; if(f[x]==-1) return x; else s...
        阅读全文
            
摘要:题意: 有一棵有 n 个节点并以 1 为根节点的树, 一开始每个节点有 1 个苹果,定义两种操作 Q i 询问以 i 为根节点的树上有多少个苹果。 C i 如果i 这个节点上有 1 个苹果就把它摘下,否在就在这个节点装上一个苹果。分析: 可以把树上的每个节点对应到树状数组中, 对应的时候,越靠近根节点的节点管辖的数组区间范围越大, 可以利用深搜,根据访问的时间戳的顺序,依次为每个节点标记在树状数组中的下限 l[i], 因为要使得越靠近叶子节点的节点管辖区间越小,可以利用深搜回溯的特点,即越靠近叶子的节点,回溯到本身的时间差越短,这个时间差即为该节点覆盖的数组区间长度,因此每个节点覆盖的数组上.
        阅读全文
            
摘要:题意: 一组造作: 0 n 创建一个 n*n 的矩形。 1 x y num 在(x,y)位置加上值 num。 2 l b r t 输出矩阵 l<=x<=r,b<=y<=t 内所有数值和。 3 退出。分析: 二维树状数组。#include<stdio.h>#include<string.h>int a[1025][1025];int n;int lowbit(int x){ return (x)&(-x);}void add(int x,int y,int num){ while(x<=n) { int ty=y; while(ty&
        阅读全文
            
摘要:题意:动物王国中有三类动物A,B,C,这三类动物的食物链构成了有趣的环形。A吃B, B吃C,C吃A。 现有N个动物,以1-N编号。每个动物都是A,B,C中的一种,但是我们并不知道它到底是哪一种。 有人用两种说法对这N个动物所构成的食物链关系进行描述: 第一种说法是"1 X Y",表示X和Y是同类。 第二种说法是"2 X Y",表示X吃Y。 此人对N个动物,用上述两种说法,一句接一句地说出K句话,这K句话有的是真的,有的是假的。当一句话满足下列三条之一时,这句话就是假话,否则就是真话。 1) 当前的话与前面的某些真的话冲突,就是假话; 2) 当前的话中X或
        阅读全文
            
摘要:题意: 给一个字符串,求出该字符串的哈夫曼编码的总长度。分析:由于没考虑树中只有一个字符的情况又WA了N 久T-T ,最近总是犯脑残的错误啊。 关于哈夫曼编码 可以看这个.... 留着复习... http://www.thecodeway.com/blog/?p=870#include<cstring>#include<cstdio>#include<queue>#include<algorithm>#define clr(x)memset(x,0,sizeof(x))using namespace std;struct node{ double
        阅读全文
            
摘要:题意: 给一串字符,有三种操作'<' '>' '-' 表示左移,右移,删除,要求输出最后结果。分析: 建立双向链表模拟之...第一个用双向链表做的题,wa了N次。。。--!View Code #include<stdio.h>#include<string.h>#include<stdlib.h>struct node{ node *next; node *pre; char c;};char s[1000005];node *a[1000005];int main(){ int n; int to
        阅读全文
            
 
                    
                

 浙公网安备 33010602011771号
浙公网安备 33010602011771号