随笔分类 -  数据结构

摘要:线段树(经典题)离散化+成段更新+区间统计题意:先输入case数,每个case输入n,表示下面有n个海报,每行就是海报的左右坐标,第i个海报的颜色为i。一面墙长度固定为10000000,问这些海报贴上去后能看到多少种颜色这个问题的难处其实是怎么离散化(也就是映射,映射后就是简单的线段树整段更新,最后区间询问)。今天第一次学离散化,说说个人的解法方法是和别人的大概一样的,可能代码实现有些不同,我的代码可能空间开销更大些(后来查看代码,很多空间能省略,但是下面的代码是我最原始的代码,并没有后来的优化,就以此来讲解)。int s[MAXN][2]; 保存原始的数据,[0]是起点坐标,[1]是终点坐标 阅读全文
posted @ 2013-02-24 00:43 Titanium 阅读(1783) 评论(0) 推荐(0)
摘要:线段树题意:输出N,T,M,表示总区间长度([1,N]),有T种颜色(1到T表示),接下来有M个操作。C,a,b,c类型的操作是成段更新,把区间[a,b]的颜色改为c。P,a,b类型的操作是询问区间[a,b]有多少种不同的颜色分析都在代码里面了/*成段更新,询问一个区间内有多少种的不同的颜色每次询问之前清空一个颜色的标记数组,然后开始询问,去到一个区间,若val为1说明整段的颜色相同,不用再继续深入,若为0说明颜色不止一种要继续深入。每次val为1时要判断这个颜色col是否已经被记录,只有没被记录的才能计数,而且要记录该颜色已经被用过至于成段更新,要用到LAZY。到达目标区间后不要再继续深入。 阅读全文
posted @ 2013-02-23 11:02 Titanium 阅读(199) 评论(0) 推荐(0)
摘要:线段树 or 树状数组 or 归并排序一个关于逆序数的问题。输入n,下面给出n个数字,分别是0到n-1,顺序不定。问你逆序数是多少?逆序数就是逆序对的个数,所谓逆序对,就是一个序列中任取两个数字,若i<j,a[i]>a[j],则称a[i]和a[j]是一个逆序对,好像3,1,4,2,逆序对有(3,1),(3,2),(4,2),所以逆序数为3但题目还没完,它还需要移动,每次将序列的第一个元素放在序列的最后,得到的新序列再求一次逆序数,可知一个长度为n的序列这样的移动可以做n-1次,可以得到n-1个新的序列,(第n次的话就会变回原始的序列)。然后问你,原序列和n-1个新序列中最小的逆序数 阅读全文
posted @ 2013-02-22 20:29 Titanium 阅读(485) 评论(0) 推荐(0)
摘要:线段树:一整段区间修改数值,并询问一段区间的和(不过这里询问的整个区间的和,固定的,当然原理是一样)这题要用到LAZY标记,决定自己写一下LAZY标记先说题意:一个连续的线段,材料可能为金银铜,数值对应3,2,1,一开始所有单元都是铜,所以整段的和就是n。然后多个修改操作,每次为x,y,z把区间[x,y]的每个单元都变为数值z。z的值为1,2,3。所有的修改操作做完后,输出整个线段的和然后说一下LAZY思想的本质,就是“只做表面功夫,内部其实不合格,当某一次需要访问到内部的时候,再对内部处理”,这种偷懒的思想就能减少操作的次数,因为每次访问到线段树的深度不一定一样,不需要全部都处理掉。这个思想 阅读全文
posted @ 2013-01-31 23:22 Titanium 阅读(488) 评论(0) 推荐(0)
摘要:线段树简单题:区间乘积,单点修改这题其实难度和之前的一样本来不想做的,但是学习了高手的代码,所以自己想实现一遍果然用了新的代码风格,时间大大提高,空间都减少,不过代码量好像没怎么变,一口气冲进了第10名10G-rated281MS1280K1572BC++2013-01-31 12:57:58#include <cstdio>#define N 50010const int MOD=1000000007;__int64 mul[4*N];int n,m;void updata(int a ,int b ,int p ,int e ,int root){ if(a==b) { ... 阅读全文
posted @ 2013-01-31 13:05 Titanium 阅读(256) 评论(0) 推荐(0)
摘要:线段树最简单的题目:区间求和,修改单点数值,中文题目就不说题意了今天看了神牛的代码感慨良多,写代码像写诗一样感觉自己的代码就是写得太累赘下次线段树要加大难度了#include <cstdio>#include <cstring>#define N 50010struct node{ int a,b; int sum;}tree[4*N];int n;void updata(int p ,int e , int root){ tree[root].sum+=e; if(tree[root].a==tree[root].b) return ; int m... 阅读全文
posted @ 2013-01-30 23:26 Titanium 阅读(195) 评论(0) 推荐(0)
摘要:线段树入门题中文题就不说题意了。就是基本的区间询问最大值和修改某个特定单元的值,初学线段树,自己硬生生啃出来的代码,写得不好,不过1Y了这道题很是鼓舞。时间上500ms,不知道那些100ms是怎么做到的#include <cstdio>#include <cstring>#define N 200010#define INF 0x3f3f3f3fstruct segment_tree{ int a,b; //区间 int l,r; //左右孩子 int max;}tree[2*N];int a[N];int tot; //线段树结点的个数int n,m; //区间长度和 阅读全文
posted @ 2013-01-29 13:37 Titanium 阅读(190) 评论(0) 推荐(0)
摘要:怎么个图论法??这题一读完题一直没有思路,不知道和图论有什么关系,倒是一开始就想到了暴力,但是见数据的规模,怕暴力会超时所以就没写一直歇了两天,没思路去找解题保报告,看了几下,都是暴力求解(和自己当初想的一样都是求lcm作为周期来计数),所以就写了一个暴力,一次成型没有debug过了sample直接丢上uva去,AC了,不过时间也比较糟糕1.100s左右。#include <cstdio>#include <cstring>#define N 1010#define M 15bool killed[N];int c[N];int a[N][M];int n;int ki 阅读全文
posted @ 2012-12-18 19:46 Titanium 阅读(595) 评论(0) 推荐(0)
摘要:并查集经典题目,详细写一下吧题意:虽然比较长,但是题意还是比较好懂的。如果a和b是朋友,b和c是朋友,那么a和c是朋友。如果a和b是敌人,c和b是敌人,那么a和c要成为朋友操作1和2是假设(或者说试图建立某种关系),如果能成立不用输出,并且保持这种关系,如果这种假设(关系)与之前已经存在的关系是冲突的,那么输出-1,并且要保持原来的关系,放弃当前这个失败的。操作3和4是判断,即根据当前已知的关系,判断某两个人之间的关系是否成立,成立输出1,不成立或者无法确定就输出01 a b 即试图让a和b成为朋友唯一不成立是:a在b的敌对集合中(那么同时b一定在a的敌对集合中)a和b有共同敌人,成立a和b至 阅读全文
posted @ 2012-12-14 22:01 Titanium 阅读(799) 评论(0) 推荐(0)
摘要:并查集裸题,可以用来学习并查集的性质1.并查集判断是否成环,如果一条边的两个点的祖先相同,那么成环2.整个祖先数组中p[i]=i个个数就是连通分量的个数题目要求:1.若没哟普任何边直接输入0 0 要输出Yes2.若成环,No3.不管是否成环,图不连通,No4.注意输入中的点是任意的,编号并不连续,所以要标记哪些点出现在输入中,没有出现在输入中的点不要管#include <cstdio>#include <cstring>#define N 100010int p[N],use[N];int find(int x){ while(x!=p[x]) x=p[x]; ret. 阅读全文
posted @ 2012-11-23 17:55 Titanium 阅读(168) 评论(0) 推荐(0)
摘要:纯粹考察并查集,算是一个经典问题;统计一个集合中有多少个元素,然后找到元素个数最多的集合就普通的并查集,就能过了然后另外写了压缩路径,没想到时间没有改变然后再写一个,时间还是没有改变,好吧……………………只要懂基本的并查集的话,代码都不成问题,很裸的并查集而已代码一:纯粹#include <cstdio>#include <cstring>#define N 30000int p[N],c[N];int n,m;int find(int x){ return p[x]==x ? x : p[x]=find(p[x]); }int main(){ int T; scanf 阅读全文
posted @ 2012-11-23 16:22 Titanium 阅读(446) 评论(0) 推荐(0)
摘要:近期所做题目中最好的一道,首先是比较创新不是常规的,另外需要比较好的数学功底能够洞察到一些小细节,然后转化方法貌似有很多,我自己想了很多但是都很差劲,最后实在没办法很无耻地找了解题报告,这篇解题报告感觉写得最好,我就是按照他的思路自己写的代码1A,佩服佩服此大神解题报告 http://hi.baidu.com/lixubd/item/1fbebd2c0389700f43634a5f算法思路都在里面了,我就不写了,我自己独立写了代码,加了很多注释,代码虽然比较多(这道题代码本来就多),然后其实不难读懂说明一点,预处理后的矩阵行和列都翻倍了,我的代码行和列都是从1开始标号的,而那位大神的代码都是从 阅读全文
posted @ 2012-11-16 23:41 Titanium 阅读(472) 评论(0) 推荐(0)
摘要:在poj上也有 是poj 1420,在poj上AC了,但是在UVA上RE题意:很好理解就是给你一个表格,一些元素已经有数字了,一些元素还不知道,但是它等于某些元素相加的和,要你补完整个表格(行用1到999表示,列用大写字母来表示,用ABC开始一直到ZZZ,这个很容易算出来,26+26*26+26*26*26=18278,字符处理有些麻烦,代码中的funtion函数)这个东西一开始没想到是什么,后来喵了一下解题报告说是拓扑排序,瞬间就懂了,因为有些元素是未知的,未知的元素是由已知的元素相加得到的,那么就是有一个优先关系,看sample就看得出来然后数据较大,打了一半不知道要怎么做了,然后又轻轻喵 阅读全文
posted @ 2012-11-14 18:10 Titanium 阅读(534) 评论(0) 推荐(0)
摘要:献上题意:个你一个转轮,有5种颜色,为了5中颜色的位置是确定的,为了方便处理我们用01234来表示绿,黑,红,蓝,白。轮子可以沿着它的方向滚动(只能是它当前的方向不能相反方向),每滚动一次会到达另一个格子,着地的颜色会改变,变了之前颜色的下一个,例如当前是绿色着地下一次就是黑色,依次是红蓝白。也可以原地转动(顺逆时针都可以),原地转动其实就是改变了轮子的滚动方向,原地转动每次能转90度。原地转动一次和滚动一次时间都是1秒。另外轮子有4个方向,上北下南左西又东。另外给你n*m个格子,有些格子不能到达,用#表示,给你起点S和终点T。在起点时轮子方向规定向北,绿色着地,然后滚动到终点,要求绿色着地, 阅读全文
posted @ 2012-11-14 15:13 Titanium 阅读(976) 评论(0) 推荐(1)
摘要:说白了还是搜索题输入n有n个点,从1到n标号,起点为1,终点为n,下面n行是每个点信息第一个数字是该点所带的能量值,第二个数字是该点的出度m,然后m个数分别是和该店相连的点的标号起点和终点的能量值都是0游戏一开始的能量值是100,没到达一个点,新的能量值等于之前的能量值加上该点的能量值,游戏要求在任何一个的时候能量值都不能小于等于0,问最后能否到达终点另外一个点是可以多次到达的这题不要想复杂了其实很好做当发现有个和为正值的环存在时,直接求看该点能否直接到达终点。如果可以,直接返回true,即winnable。否则,不用做任何的标记。因为不会再去探索它是否可以直接到达终点。在搜索的过程中看看有没 阅读全文
posted @ 2012-11-13 09:53 Titanium 阅读(504) 评论(0) 推荐(0)
摘要:图的搜索,双重搜索题意:(折腾的UVA又是好难懂的题意),给你一个h行w列的矩阵输入(标准的),注意输出w h,别颠倒过来。然后只有三种点 '*' , '.' , 'X'其中X和*一起称为区域I,在区域I中相连的X称为区域II , 输出就是输出m个数字,其中m就是区域I的个数,这m个数字中第i个数字num[i]表示某块区域I一面又多少个区域II其中相连是两个格子有公共边,只有点不行,所以对于一个格子而言有4个相连的格子,分别就是上下左右另外区域I可能是任意形状的,可以看samplesample中就是有4块区域I左上角的区域I有两个X,但是这个两个 阅读全文
posted @ 2012-11-11 00:55 Titanium 阅读(732) 评论(0) 推荐(0)
摘要:一样的题目,看poj 1386 Play on Words即可 阅读全文
posted @ 2012-11-10 20:06 Titanium 阅读(312) 评论(0) 推荐(0)
摘要:再学欧拉路无力再写题解报告了,最近写得最难受的一道题,前前后后调试了有10来个小时,就一个这么个BUG#define N 30#define MAX 1010开某些数组的时候把N和MAX写反了但是…………代码还是有问题的,G++一直过不了,一直是WA,C++可以过,等下还要调试,一定要把G++给过了题意:和poj 1386 是一样的题目,不过这次要输出路径,而且要字典序最小做法:用邻接表来构建有向图(我的构建方法和网上找来的不一样,不是用白书介绍的那种模拟链表的头插法,而是直接一点,比较然后插入,已有的元素向后移,感觉在时间上没什么差距)。然后用并查集来判断有向图的基图是否连通(其实直接用邻接 阅读全文
posted @ 2012-11-10 17:58 Titanium 阅读(277) 评论(0) 推荐(0)
摘要:再学欧拉路,没搞清楚定理错了好几次题意:给你n个单词,要求这些单词相连,要求是前面的字母的尾字母和后面单词的头字母相同,问你这n个单词能不能全部连起来,可以连成一条链或者连成一个环另外单词只有小写字母。很容易想到,顶点集合就是26个小写字母,用1到26来表示,一个单词的首字母和尾字母就是一条有向边,注意是有向边,因为单词是不能倒回来的其实就是问你这个图是否存在欧拉道路(一条链的情况)或者欧拉回路(环的情况),反正存在欧拉路就是成功的,否则就是失败判断有向图是否有欧拉路1.判断有向图的基图(即有向图转化为无向图)连通性,用简单的DFS即可。如果图都不连通,一定不存在欧拉路2.在条件1的基础上 对 阅读全文
posted @ 2012-11-09 20:44 Titanium 阅读(662) 评论(0) 推荐(2)
摘要:推荐技术公众号:不爱睡觉的大猪 题意:给你n个珠子,一个珠子分为两半有两种颜色,用1到50来表示50种不同的颜色。把这些珠子串起来,两个紧挨着的珠子要满足一个条件就是接触的那部分颜色要相同 例如(1,2)(2,4),两个珠子的接触部分颜色相同都为2。当然,因为珠子最后是连成环的,第一个珠子和最后一个 阅读全文
posted @ 2012-11-09 12:19 Titanium 阅读(2246) 评论(1) 推荐(4)