2012年1月13日
摘要: SGU_123 斐波那契数列前n项和为2*F(n+1)-F(n-1)-1。#include<stdio.h>#include<string.h>long long int f[50];int main(){ int i, j, k; f[0] = 0, f[1] = 1; for(i = 2; i <= 41; i ++) f[i] = f[i - 1] + f[i - 2]; while(scanf("%d", &k) == 1) printf("%d\n", f[k + 1] - f[k - 1] - 1 + f 阅读全文
posted @ 2012-01-13 22:46 Staginner 阅读(144) 评论(0) 推荐(0) 编辑
摘要: SGU_117 直接应用快速幂取模即可。#include<stdio.h>#include<string.h>int N, M, K;int pow_mod(int a, int n){ int ans; if(n == 1) return a % K; ans = pow_mod(a, n / 2); ans = ans * ans % K; if(n % 2) return ans * a % K; else return ans;}void solve(){ int i, d, cnt = 0; f... 阅读全文
posted @ 2012-01-13 21:27 Staginner 阅读(209) 评论(0) 推荐(0) 编辑
摘要: POJ_1204 其实POJ这个题目叙述得不太严谨,所以我就先做SPOJ上这个题去了,回来之后交了一下倒是也过了。这个题目可以用AC自动机去做,为了能够在匹配完单词后顺利找到单词首位置,我们可以选择把单词反过来建字母树,这样最后一个字符实际上就是第一个字符。 在后面查找的时候可以做一个小优化,就是找过的字典树上的结点的标记置为-1,以后再遇到这个结点就直接break而没必要再沿着预处理的标记向上寻找了。#include<stdio.h>#include<string.h>#define MAXD 800010#define MAXN 1010char b[MAXN][M 阅读全文
posted @ 2012-01-13 19:55 Staginner 阅读(327) 评论(0) 推荐(0) 编辑
摘要: HDU_2222 今天开始学AC自动机了,这个就是我AC自动机的处女作了。这个题有个小trick就是单词列表中可能有重复的单词,但这些重复的单词应看做不同的,因此建字典树时做标记的时候,把原来的赋值为1的操作变为自加1的操作即可。 最后匹配的时候有一个小优化,就是比如当前正在看有多少个以j结点的字符为结尾的单词,那么我们还需要不停地沿预处理的标记向上找,当我们找过之后就可以把当前节点的标记做成-1,以后再遇到-1的时候,就直接break,无需再沿着标记向上找了,因为上面的结点一定在之前就找过了。这个优化大概能节省400ms的时间。#include<stdio.h>#include& 阅读全文
posted @ 2012-01-13 16:16 Staginner 阅读(291) 评论(3) 推荐(0) 编辑
摘要: POJ_2752 将字符串对自己进行KMP匹配即可,也即进行一般的KMP问题的预处理的步骤。之后去找恰好匹配到最后一个字符的所有可能的前缀的长度即可,也就是遍历一遍P[N],其中N为字符串的长度。#include<stdio.h>#include<string.h>#define MAXD 400010char b[MAXD];int P[MAXD];void printresult(int k){ if(P[k] == 0) printf("%d", k); else { printresult(P[k]); printf(" %d... 阅读全文
posted @ 2012-01-13 00:07 Staginner 阅读(174) 评论(0) 推荐(0) 编辑