09 2013 档案

摘要:HDU 3746 Cyclic Nacklace ( KMP求最小循环节 )len - nextval[len]即为最小循环节长度。#include #include #include #include using namespace std;const int MAXN = 100100;const int INF = 1 #include #include #include using namespace std;const int MAXN = 1000010;char str[MAXN];int nextval[MAXN];int len;void getNext( char s[]. 阅读全文
posted @ 2013-09-29 21:04 冰鸮 阅读(312) 评论(0) 推荐(0) 编辑
摘要:dp[i]代表前i个字符组成的串中所有前缀出现的次数。dp[i] = dp[next[i]] + 1;因为next函数的含义是str[1]~str[ next[i] ]等于str[ len-next[i]+1 ]~str[len],即串的前缀后缀中最长的公共长度。对于串ababa,所有前缀为:a, ab,aba,abab, ababa, dp[3] = 3;到达dp[5]的时候,next = 3, 它与前面的最长公共前缀为aba,因此dp[5]的凑法应该加上dp[3],再+1是加上ababa它本身。说不太清楚……从感觉上比较类似于那个“给你几种面值的硬币,问凑出指定钱数的所有凑法”的dp方式。 阅读全文
posted @ 2013-09-29 14:40 冰鸮 阅读(215) 评论(0) 推荐(0) 编辑
摘要:设串为str, 串长为len。对整个串求一遍next函数,从串结尾开始顺着next函数往前找#include #include #include using namespace std;const int MAXN = 1000100;char str[MAXN];char tmp[MAXN];int nextval[MAXN];int len;void GetNextVal( char *s, int lenth ){ int i = 0, j = -1; nextval[0] = -1; while ( i len/3 ) ans = nextval[ans]; ... 阅读全文
posted @ 2013-09-29 09:18 冰鸮 阅读(285) 评论(0) 推荐(0) 编辑
摘要:一开始看的时候就想歪了,比赛的时候一直在YY线段树区间覆盖,然后纠结节点数太多开不下怎么办啊啊啊啊……然后昨天吃饭的时候也在纠结这到底是个啥题,后来发现公共前缀->前缀??!!!!->这不是很显然的Trie么……QAQ举例说明:对于subnet: 123.45.4.0/22,转化成二进制后,取前22位(长度由子网掩码决定)加入Trie树,后面的IP一定是0所以无意义,然后每个节点开一个vector保存能到达这个节点的所有子网的Pid,以及该子网IP的最大值。对于ip_src:查找它所属于的所有子网组的Pid,并标记出来。对于ip_dst:看它与ip_src所属的所有子网组的Pid跟 阅读全文
posted @ 2013-09-29 09:06 冰鸮 阅读(477) 评论(0) 推荐(0) 编辑
摘要:按边从小到大排序。对于每条边(from, to, dist),如果from和to在同一个集合中,那么这条边无意义,因为之前肯定有比它更小的边连接了from和to。如果from和to不属于同一个集合,那么增加这条边后增加的点对数目是cnt[from]*cnt[to]*2( 因为(u, v)和(v, u)不算同一点对,所以*2 )统计出所有点对数total。对于查询,按t值从小到大排序,边从小到大一条一条往里加。tmpSum为f值小于t的点对总数。当边权大于等于t值时:ans[i] = total - tmpSum。当边权小于t值时,更新tmpSum。#include #include #incl 阅读全文
posted @ 2013-09-26 21:09 冰鸮 阅读(204) 评论(0) 推荐(0) 编辑
摘要:卖切糕的小女孩http://www.cnblogs.com/wuyiqi/archive/2012/04/28/2474672.html#include #include #include #define lson l, m, rt > 1; build( lson ); build( rson ); return;}void PushUp( int rt ){ cnt[rt] = cnt[lc] + cnt[rc]; for ( int i = 0; i > 1; if ( L maxAve ) { maxAve = ... 阅读全文
posted @ 2013-09-25 22:42 冰鸮 阅读(459) 评论(0) 推荐(0) 编辑
摘要:把点编号改成1-N,加一点0,从0点到之前任意入度为0的点之间连一条边权为0的边,求0点到所有点的最长路。SPFA模板留底用#include #include #include #include #include #include #include #define ll long long#define inf 1000000000#define maxn 1010using namespace std;struct Edge{ int from,to; int dist; Edge(int a,int b,int c) { from=a,to=b,dis... 阅读全文
posted @ 2013-09-25 10:56 冰鸮 阅读(342) 评论(0) 推荐(0) 编辑
摘要:与其说这是个博弈,倒不如说是个搜索。这题思路不错,感觉很难把情况考虑周全。在地图外围填充一圈0,两次BFS,第一次从-1点出发,把从-1到达的0点以及包围0的那一圈石头标记出来。如下图:6 71 1 1 1 1 1 11 0 0 0 0 0 11 0 3 5 1 1 11 0 -1 4 0 1 11 0 1 0 0 1 11 1 1 1 1 1 1第二次BFS,从外围(0,0)点出发,找出外面与标记石头的交界层:6 71 1 1 1 1 1 11 0 0 0 0 0 11 0 3 5 1 1... 阅读全文
posted @ 2013-09-25 10:48 冰鸮 阅读(278) 评论(0) 推荐(0) 编辑
摘要:两种做法。第一种:标记区间最大值和最小值,若区间最小值>=P,则本区间+2c,若区间最大值#include #include #define lson l, m, rt > 1; build( lson ); build( rson ); return;}inline void PushDown( int rt, int m ){ if ( lazy[rt] ) { lazy[lc] += lazy[rt]; lazy[rc] += lazy[rt]; sum[lc] += lazy[rt]*(m - (m >> 1) )... 阅读全文
posted @ 2013-09-24 22:09 冰鸮 阅读(261) 评论(0) 推荐(0) 编辑
摘要:题意:给你三种颜色表示模式,RGB,HSV和HSL,实现任意模式之间两两转化。1.最好别看题目中给的转化公式描述,我觉得叙述的一点也不清楚,看维基百科,把维基百科上的公式一句一句翻译过来就好2.在公式换算的时候,全部转成小数形式。例如:RGB的取值范围0-255转化成0-1, 即r = R/255.0, g = G/255.0 b = B/255.0……3.HSL->RGB和HSV->RGB需要四舍五入,而HSV和HSL之间的互相转化需要通过RGB: HSVRGBHSL,这里转RGB的时候不需要四舍五入。4.对于自己转自己的情况,例如RGB->RGB,直接原样输出。写的时候脑 阅读全文
posted @ 2013-09-23 21:24 冰鸮 阅读(242) 评论(0) 推荐(0) 编辑
摘要:题意:给你两个串A,B,问一个串长为M+N且包含A和B且恰好包含M个R的字符串有多少种组合方式,所有字符串中均只含有字符L和R。dp[i][j][k][S]表示串长为i,有j个R,在自动机中的状态为k,包含AB的状态为S的方案个数。PS1.之前用long long int超时了两次PS2.把行列搞错了WA了几次#include #include #include #include //#define LL long long intusing namespace std;const int MAX_NODE = 1210;const int CHILD_NUM = 2;const int MA 阅读全文
posted @ 2013-09-23 20:51 冰鸮 阅读(368) 评论(0) 推荐(0) 编辑
摘要:都是从网上找的,交过题试过的应该没问题的模板。KMP//未优化的next函数void getNext(char s[],int next[]){ int length=strlen(s); int i=0,j=-1; next[0]=-1; while(i#includeusing namespace std;const int MM=100005;int next[MM],extand[MM];char S[MM],T[MM];void GetNext(const char *T){ int len=strlen(T),a=0; next[0]=len... 阅读全文
posted @ 2013-09-19 17:09 冰鸮 阅读(269) 评论(0) 推荐(0) 编辑
摘要:模板来自notonlysuccess.模式串只有10个,并且重复出现的分值不累加,因此很容易想到状态压缩。将模式串加入AC自动机,最多有10*100个状态。dp[i][j][k]:串长为i,在Trie图上的状态为j,已经包含的模式串为k(二进制表示,第x位为1代表已经包含第x个串)。dp[i][j][k]为true或false代表该状态是否可达。沿着Trie图中的边走进行DP,时间复杂度O( 100*1000*1024 );最后枚举一下串长为L的所有可达状态,最大值即为结果。PS.内存有限,需要用滚动数组PS2.若使用静态队列的话,队列大小最好开状态数的二倍或者更多#include #incl 阅读全文
posted @ 2013-09-19 17:07 冰鸮 阅读(254) 评论(0) 推荐(0) 编辑
摘要:方法参见:http://blog.acmol.com/?p=751从最后一个线段开始倒着处理(因为之后的线段不会被它之前的线段覆盖),把这条线段所覆盖的所有线段编号合并到一个集合里,并以最左边线段编号为父结点。然后,以后的线段每次都是从右端向左端进行以下处理:1、判断该线段在并查集中的根结点是否被覆盖过(用一个数组标记),如果没有被覆盖,则将该线段所在集合与海报左端点所在集合进行合并(以左端点所在集合为根)。2、然后开始处理刚处理过的线段父结点左边的那一个线段,处理方法与第1步时一样。3、直到要处理的线段在左端点的左边时停止循环。处理时,如果有一个线段未被覆盖,就证明该点的染色没有被之后的染色 阅读全文
posted @ 2013-09-17 22:17 冰鸮 阅读(510) 评论(0) 推荐(0) 编辑
摘要:参考:http://www.cnblogs.com/oyking/p/3323306.html相当不错的思路,膜拜之~个人理解改日补充。#include #include #include #include #define lson l, m, rt > 1 ) ); maxi[rc] = mini[rc] = mini[rt]; sum[rc] = (LL)maxi[rt]*( m >> 1 ); } return;}void PushUp( int rt ){ sum[rt] = sum[lc] + sum[rc]; maxi[rt] =... 阅读全文
posted @ 2013-09-16 20:58 冰鸮 阅读(316) 评论(0) 推荐(0) 编辑
摘要:来源: 吴垠的日志一些题外话首先就是我为什么要写这么一篇日志。原因很简单,就是因为前几天有个想起步做ACM人很诚恳的问我该如何入门。其实就现在而言,我并不是很想和人再去讨论这样的话题,特别是当我发现我有很多的东西要学的时候,我实在是不想花太多的时间在这种问题上。但是我当年也是纯凭热情搞ACM过来的,实在是不忍心打击一个同样有着满腔热情的起步者。所以干脆就多花点时间,总结一下我的一些观点和看法,以后再让人问起这个问题的时候,也好不用再重复什么了。其次,我在这篇文章中并不打算探讨特别细节的问题,比如说如果某些人想从中得到诸如“该看哪本书入门比较好”或者“动态规划、搜索、图论该怎么学”之类问题的答案 阅读全文
posted @ 2013-09-15 22:35 冰鸮 阅读(238) 评论(0) 推荐(0) 编辑
摘要:空间异面直线的距离直接套模板。求交点:求出两条直线的公共法向量,其中一条直线与法向量构成的平面 与 另一条直线 的交点即可。还是套模板o(╯□╰)o1.不会有两条线平行的情况。2.两条直线可能相交#include #include #include #include #include using namespace std;const double EPS = 1e-9;const int MAXN = 40;struct Point3 //空间点{ double x, y, z; Point3( double x=0, double y=0, double z=0 ): x(x... 阅读全文
posted @ 2013-09-15 19:38 冰鸮 阅读(533) 评论(0) 推荐(0) 编辑
摘要:线段树成段更新+区间最值。注意某人的乘车区间是[a, b-1],因为他在b站就下车了。#include #include #include #include #define lson l, m, rt > 1; build( lson ); build( rson ); return;}void PushUp( int rt ){ maxi[rt] = max( maxi[lc], maxi[rc] ); return;}void PushDown( int rt ){ if ( lazy[rt] ) { lazy[lc] += lazy... 阅读全文
posted @ 2013-09-15 11:01 冰鸮 阅读(243) 评论(0) 推荐(0) 编辑
摘要:M=1:aaaaaaaa……M=2:DFS+manacher, 暴出N=1~25的最优解,找规律。N8时,头两个字母一定是aa,剩下的以aababb循环,最后剩余#include using namespace std;const char str[] = "aababb";int main(){ int T; int cas = 0; scanf( "%d", &T ); while ( T-- ) { int M, N; scanf( "%d%d", &M, &N ); printf("Case 阅读全文
posted @ 2013-09-14 21:54 冰鸮 阅读(252) 评论(0) 推荐(0) 编辑
摘要:成功袭击次数=所有袭击次数-成功防守次数需要一个辅助pre来记录上一次袭击成功什么时候,对于每个查询,从上一次袭击成功开始,每隔t更新一次。感觉这样做最坏时间复杂度是O(n^2),这里 说是O(q)*O(q/t)log(n),应该是超时边缘。能AC或许因为数据不强。PS.初始化的时候直接memset会超时,每次根据N的大小build线段树,memset也根据N的大小来就能AC。#include #include #include #define lson l, m, rt >1)); sum[rc] += flag[rt]*(m>>1); flag[rt] = 0;... 阅读全文
posted @ 2013-09-14 21:30 冰鸮 阅读(220) 评论(0) 推荐(0) 编辑
摘要:以下摘自SPOJ泛做表格:题意:给定一个星形多边形,而且给出了一个可以看到形内所有点的位置(我们称这个点为观察点),让你判断有多少个点位于多边形内。时间复杂度:O(mlogn)将多边形上的点按极角排序,观察点与多边形上任意相邻两点形成若干个三角形,再按照极角查找给定点可能位于哪个三角形,最后用叉积判断它是否真的在那个三角形内。注意细节,给几组数据:input84 12 2-2 22 -2-2 -23 36 62 24 46 6-3 1-1 -15 15 12 26 67 71 13 322 152 02 24 45 51 50 5-1 5-5 5-4 4-3 3-2 2-2 0-2 -2-3 阅读全文
posted @ 2013-09-13 22:22 冰鸮 阅读(304) 评论(0) 推荐(0) 编辑
摘要:《训练指南》p.108#include #include #include using namespace std;const int MOD = 1000007;const int MAXN = 500;int C[MAXN][MAXN];void init(){ memset( C, 0, sizeof(C) ); C[0][0] = 1; for ( int i = 0; i < MAXN; ++i ) { C[i][0] = C[i][i] = 1; for ( int j = 1; j < i; ++j ) C[i][... 阅读全文
posted @ 2013-09-11 21:42 冰鸮 阅读(182) 评论(0) 推荐(0) 编辑
摘要:统计正面看高度为i的竖条个数为cnt1[i],统计侧面看高度为i的竖条个数为cnt2[i];ans = sum( i * max( cnt1[i], cnt2[i] ) ); ( 1 #include #include #include using namespace std;int cnt1[30];int cnt2[30];int main(){ int W, D; while ( scanf( "%d%d", &W, &D ), W || D ) { memset( cnt1, 0, sizeof(cnt1) ); memset( cnt2,... 阅读全文
posted @ 2013-09-11 20:54 冰鸮 阅读(252) 评论(0) 推荐(0) 编辑
摘要:主要是建图,建好图之后跑一边dijkstra即可。一共3N个点,1~N是原图中的点1~N,然后把每层x拆成两个点(N+x)[用于连指向x层的边]和(N+N+x)[用于连从x层指出的边]。相邻层节点互相可达:AddEdge( N+N+x+1, N+x, C), AddEdge( N+N+x, N+x+1, C);对于位于x层的节点i,AddEdge(N+x, i, 0), AddEdge(i, N+N+x, 0);#include #include #include #include #include using namespace std;const int MAXN = 100010*3;c 阅读全文
posted @ 2013-09-11 20:32 冰鸮 阅读(338) 评论(0) 推荐(0) 编辑
摘要:参考了:http://www.cnblogs.com/zhsl/archive/2013/08/10/3250755.htmlhttp://blog.csdn.net/chaobaimingtian/article/details/9852761题意:一个有n个节点的树,每个节点存有一份独一无二的信息,要求用最小的步数,把每个节点的信息共享给所有的节点。一个节点把自己所包含的所有信息传递给相邻的一个节点为一步。题目不是求最小的步数,而是问最小的步数下,信息传递的方法有多少种。分析:最小步数:所有节点把信息传给同一个节点,再由这个节点传给其他节点。因此最小步数为树边数的2倍,即2*(n-1)。我 阅读全文
posted @ 2013-09-10 18:39 冰鸮 阅读(606) 评论(0) 推荐(0) 编辑
摘要:训练指南p.59#include #include #include #include using namespace std;const int MAXN = 30;int N;int A[MAXN];char str[1010];map table;int bitcount( int x ){ int res = 0; while ( x ) { if ( x & 1 ) ++res; x >>= 1; } return res;}int main(){ while ( scanf( "%d", &N ) == 1 ) ... 阅读全文
posted @ 2013-09-09 16:33 冰鸮 阅读(271) 评论(0) 推荐(0) 编辑
摘要:假设最少删除的边的个数为cost,显然,最终答案即为cost+cost+1 (因为删除一条边,就会增加一个链,所以删除cost条边后,就会有cost+1条链,将这cost+1条链连接起来的代价为cost+1, 删除cost条边的代价为cost,所以总代价为cost+cost+1)求最少删除的边数:首先我们定义一棵子树中的链不能以该子树的根为端点,以下提到的所有链均必须满足这个条件。设一棵以节点i为根的子树中,叶子节点的个数为duan,并设i的父亲为fa。那么,这棵子树至少会分割成duan-1条链(以其中两个叶子为端形成一条链,剩下的一个叶子对应一条链)。DFS,对于某棵以节点i为根的子树,如果 阅读全文
posted @ 2013-09-08 21:55 冰鸮 阅读(451) 评论(0) 推荐(0) 编辑
摘要:双向链表直接模拟。用一个辅助数组maxSum来维护一下前k项中[1,k]的最大和。因为光标是一格一格的移动,所以每次光标右移的时候动态更新一下即可。时间复杂度O(n)。#include #include #include #include using namespace std;const int MAXN = 1000100;const int INF = 1 pre = NULL; head->next = NULL; node *cur = head; maxSum[0] = -INF; sum[0] = 0; int... 阅读全文
posted @ 2013-09-07 21:58 冰鸮 阅读(297) 评论(0) 推荐(0) 编辑
摘要:起点和终点各做一次单源最短路, d1[i], d2[i]分别代表起点到i点的最短路和终点到i点的最短路,枚举商业线车票cost(a, b); ans = min( d1[a] + cost(a, b) + d2[b] );#include #include #include #include #include #include using namespace std;const int MAXN = 1010;const int INF = 1 rhs.d; }};struct Edge{ int from, to, dist; Edge() { } Edge( i... 阅读全文
posted @ 2013-09-07 16:45 冰鸮 阅读(207) 评论(0) 推荐(0) 编辑
摘要:《训练指南》p.125设f[n] = gcd(1, n) + gcd(2, n) + …… + gcd(n - 1, n);则所求答案为S[n] = f[2]+f[3]+……+f[n];求出f[n]即可递推求得S[n]:S[n] = S[n - 1] + f[n];所有gcd(x, n)的值都是n的约数,按照约数进行分类,令g(n, i)表示满足gcd(x, n) = i && x #include #include #include #define LL long long intusing namespace std;const int MAXN = 4000100;LL 阅读全文
posted @ 2013-09-05 21:47 冰鸮 阅读(201) 评论(0) 推荐(0) 编辑
摘要:构造矩阵.见《训练指南》p156...#include #include #include #define LL long long intusing namespace std;const int MAXN = 20;LL mod;struct Matrix{ LL a[MAXN][MAXN]; int r, c; friend Matrix operator*( Matrix &a, Matrix &b ); friend Matrix operator^( Matrix a, LL k );};Matrix operator*( Matrix &a, Matrix 阅读全文
posted @ 2013-09-05 09:15 冰鸮 阅读(253) 评论(0) 推荐(0) 编辑
摘要:参考:http://www.cnblogs.com/slon/archive/2012/03/30/2426104.html题意:给一个有n个点的点集,有q个询问,每个询问询问一个点p,求与p曼哈顿距离最小的点,并输出曼哈顿距离的最小值。分析:使得abs(qx - xi) + abs(qy - yi)最小,因为带了个绝对值,所以没法直接套用一些数据结构中查询最值的操作,一时间也没什么头绪。后来看到上面的博客,才明白可以分情况讨论,把绝对值去掉。一共四种情况:qx >= xi && qy >= yiqx >= xi && qy = yiqx xi 阅读全文
posted @ 2013-09-04 22:22 冰鸮 阅读(424) 评论(0) 推荐(0) 编辑
摘要:将每个球按输入顺序编号,建立 它第几个被扔掉->编号 的映射关系。记录当前在手里的球的编号,按扔掉的顺序查找这个球的编号,看看这个球是逆时针转到手里更近还是顺时针转到手里更近,即当前扔掉球的编号与当前手里球的编号之间有几个球。树状数组C[i]记录编号i的球是否还在。球是环形排列的,特殊处理一下。对于扔掉一个球之后下一个落在手里的球的编号,二分判定,找顺时针方向第一个有球的位置#include #include #include #include #define LL long long intusing namespace std;const int MAXN = 100100;int 阅读全文
posted @ 2013-09-02 22:24 冰鸮 阅读(214) 评论(0) 推荐(0) 编辑
摘要:二分爆炸半径R,判断是否可行,如果可行,半径可以继续增加。之前建图有误,结果一直不对。#include #include #include #include #include #include using namespace std;const int MAXN = 222;const double eps = 1e-5;struct Point{ double x, y; Point( double x = 0.0, double y = 0.0 ): x(x), y(y) { } void readPoint() { scanf( "%lf%lf", ... 阅读全文
posted @ 2013-09-02 22:07 冰鸮 阅读(181) 评论(0) 推荐(0) 编辑

点击右上角即可分享
微信分享提示