
其他oj
Icefox_zhx
这个作者很懒,什么都没留下…
展开
-
SPOJ694&SPOJ705(后缀数组)
这俩题一样。。就后者数据范围大些。题目:给定一个字符串,求不相同的子串的个数。每个子串一定是某个后缀的前缀,那么原问题等价于求所有后缀之间的不相同的前缀的个数。从1到n扫一遍,每一个suffix[sa[i]]的贡献为 n-sa[i]+1- height[i].(sa[i]的前缀个数-重复个数)#include #include #define N 50010int n,m,r原创 2017-07-17 16:26:55 · 583 阅读 · 0 评论 -
ural1297Palindrome (后缀数组+lcp)
求最长回文子串,且此题要求最先出现,SA+lcp解决。原想法:首先反转,拼接原串与反转串,然后求两者的最长公共前缀,唯一注意的是如果有多组要输出最先出现那一组。原想法是错误的。反例:zzzdzaadzzz。可以自己摸索下,实在不行,来这位大神博客下拜读一下也是可以的。传送门正解:首先要在本身与镜像之间插入一个特殊的,不可能出现的字符。我们枚举每一个原始字符串中的字符以它为中心(原创 2017-07-17 21:43:15 · 308 阅读 · 0 评论 -
SPOJ687 Repeats (后缀数组+lcp)
求循环节个数最大的子串的循环节个数。很绕吧。。基本和poj3693相同,此题要简单些。因为我先看了hzw的poj3693的题解。。所以我也写的是反过来做一遍求l。先入为主了呢。。网上还有很多人写的其实不需要反过来做一遍去求l,大家可以去借鉴下。。我觉得时间上差不多。。所以就懒得改了呢。。(思路有问题还是参考3693吧。。)#include #include #define N 50010原创 2017-07-18 18:48:11 · 412 阅读 · 0 评论 -
spoj D-query (莫队)
查一段区间出现的不同数字个数,赤裸裸的莫队。网上那些spoj的题号都是哪来的。。我怎么找不到题号呢。。#include #include #include #include #define ll long long#define M 200005using namespace std;int n,m,f[1000005],a[30005],ANS[M],block,ans;原创 2017-07-19 16:07:32 · 332 阅读 · 0 评论 -
tyvj1463 智商问题
本来想找到分块写的,看到了这道题,然而正解应该是二分,结果我写了stl???看到一些oier的回忆录,有些感伤。对自己的前途感到一丝彷徨,就随便水了一道题。#include #include #include #define inf 0x7fffffffusing namespace std;int const N=1000005;int n,a[N];inline int re原创 2017-07-19 22:14:54 · 365 阅读 · 0 评论 -
spoj_cot2 Count on a tree II(树上莫队+离散化)
题意:给两个点u,v,询问两点路径上有多少种不同的权值。树上莫队。然后权值要离散化。树上区间转移呢,基本就是这样的:记上次询问的两点为lastu,lastv,现在询问的两点为u,v,那么对于路径(lastu,u)上的所有点的存在性取反(就是原来答案里有就删掉,没有就加上),对于(lastv,v)同理。但是因为还有讨厌的lca的存在,所以我们一直都没把lca放在答案里。最后记答案时单独处理lca。具原创 2017-07-20 15:30:12 · 513 阅读 · 0 评论 -
luogu1970【2013提高】花匠(DP/贪心)
求最长抖动序列。首先很直白的dp:令f[i][1]表示以i为结尾,且降序到达a[i]的最长抖动序列长度;令f[i][0]表示以i为结尾,且升序到达a[i]的最长抖动序列长度。则有如下递推公式: f[i][0]=max{f[j][1]}+1,1≤j<i且h[j]<h[i]f[i][0]=max\{f[j][1]\}+1,1≤j<i且h[j]<h[i] f[i][1]=max{f[j][0]}+1原创 2017-07-29 15:02:19 · 358 阅读 · 0 评论 -
luogu1077【2012普及】 摆花(dp)
f[i][j]表示用前i种花,摆j盆的方案数。原创 2017-07-29 11:05:24 · 351 阅读 · 0 评论 -
luogu1057【2008普及】传球游戏(dp)
f[i][j]表示第i次传球后,球在第j位。#include<cstdio> #include<cstring> int n,m,f[50][50]; int main(){ //freopen("a.in","r",stdin); scanf("%d%d",&n,&m); memset(f,0,sizeof(f)); f[0][1]=1; //第0次传球原创 2017-07-29 16:13:27 · 329 阅读 · 0 评论 -
luogu1020【1999提高】导弹拦截(dp)
求最长不上升子序列的板子。 这道题,对于最长上升子序列来说,每一个点都只能用一套新的导弹系统来拦截。原创 2017-07-29 16:24:52 · 292 阅读 · 0 评论 -
ural1183&&poj1141 Brackets Sequence(区间DP+记录路径)
黑书动规1.5.1例题1,原题多了记录路径,要递归打印出来。 dp[i][j]表示s[i…j]需加至少多少个括号才能变成合法的。原创 2017-07-29 11:47:27 · 302 阅读 · 0 评论 -
luogu1091【2004提高】合唱队形(dp)
#include<cstdio>int n,a[101],f1[101],f2[101],ans=0;int main(){ //freopen("a.in","r",stdin); scanf("%d",&n); for(int i=1;i<=n;i++) scanf("%d",&a[i]); for(int i=1;i<=n;i++){ //求从左到右最长上原创 2017-07-29 16:35:56 · 288 阅读 · 0 评论 -
luogu1280 尼克的任务(dp)
倒着推,f[i]表示此时刻开始选择工作,能获得的最大休息时间。 状态转移: if(这时刻没工作)f[i]=f[i+1]+1; if(这时候有一或多个工作)f[i]=max( f[ i+k[i] ] ); ps:应该按开始时间排下序的。。我懒忘敲了居然A了。。#include<cstdio>#include<cstring>#include<iostream>using namespac原创 2017-07-29 16:51:09 · 368 阅读 · 0 评论 -
sicily1822 Fight club(dp)
黑书1.5.1例题3 1822 . Fight Club原创 2017-07-30 12:37:29 · 425 阅读 · 2 评论 -
uva1291 Dance Dance Revolution(dp)
黑书1.5.1例题4.舞蹈家怀特先生。 dp[i][x][y] 表示跳完第i个舞步,左脚在x,右脚在y所需花费的最小体力。状态转移方程: dp[i][x][a[i]]=min(dp[i][x][a[i]],dp[i−1][x][y]+move(y,a[i]))dp[i][x][a[i]]=min(dp[i][x][a[i]],dp[i-1][x][y]+move(y,a[i]))dp[i][a[原创 2017-07-30 13:22:52 · 345 阅读 · 0 评论 -
luogu1002【2002普及】过河卒(递推)
递推。原创 2017-07-29 16:28:50 · 668 阅读 · 0 评论 -
luogu1004 【2000提高】方格取数(dp)
这水题我居然还想了半天。。傻死我自己得了。首先要明确,两次从(1,1)走到(n,n)都需要走2*n步。所以可以两次一起走。对于一个点(m,n)两次都只可能在走第m+n步时经过,所以只需在当次判断是否重复,其他时候都绝对不会重复。朴素的是dp[x1][y1][x2][y2],第一次走到x1,y1,第二次走到x2,y2.O(n4)O(n^4),优化一下,dp[k][i][j],走到第i步了,第一次向下走原创 2017-07-30 18:04:33 · 555 阅读 · 0 评论 -
cogs261 [NOI1997] 积木游戏(dp)
黑书1.5.1例题5 积木游戏 刚开始想按黑书那样去写,四层状态,倒着推。然后,2h过去了,爆炸。从网上搜了搜,等等,你们怎么都就三层状态?认真看一下,woc,我一定是傻疯了写四层。然后瞬间ac。看到一个写四层的,基本都是记忆化搜索过了。我倒推好弱。。推不明白。还是正推好一些。。(网上神犇纷纷表示,这是一道dp水题,好吧orz)说正解,基本都写注释里了:)状态O(mn)O(mn),决策O(n)O(原创 2017-07-30 16:28:51 · 404 阅读 · 0 评论 -
luogu1052 【2005提高】过河 (压缩状态)
显然的状态转移方程:dp[i]=min(dp[i-j]+stone[i],s<=j<=t),然而L过大,我们要想办法压缩。我们把石子按位置升序排序,设第i块石子的位置为x,第i+1块石子的位置为y。如果y-x>t,那么对于x+t+p<<y,dp[x+t+p]一定是dp[x+p]…dp[x+t+p-1]中的某个值。重复了,因此我们可以只留t个点。对于y本来可能取到的最优值,他一定在留下的t个点之内。至原创 2017-07-31 14:52:24 · 480 阅读 · 0 评论 -
luogu1115 最大子段和(递推/分治)
一直记着之前得到的能接着连下去的最大值tmp,始终更新答案ans。原创 2017-07-31 15:04:57 · 616 阅读 · 0 评论 -
P1095 守望者的逃离【2007普及】(贪心)
说实话我都有点分不清这是贪心还是dp了。。。说dp吧连个状态都没有。。。还是算他贪心吧。。。假设有两个人一起逃跑,一个只run,一个只blink(没蓝了就停下回蓝),如果blink大于run了,run就拿过blink来接着跑。。所以run就是t0时跑的最远距离了。原创 2017-07-31 15:15:21 · 440 阅读 · 0 评论 -
luogu1048 【2005普及】采药(背包dp)
01背包。原创 2017-07-31 15:54:53 · 342 阅读 · 0 评论 -
luogu1049 【2001普及】装箱问题(dp)
f[i]表示能否装出i这个体积。枚举即可。找到能装的最大合法体积。原创 2017-07-31 13:22:50 · 291 阅读 · 0 评论 -
bailian4102:宠物小精灵之收服(二维费用的01背包)
dp[i][j]表示扔i个球,皮卡丘损失j体力时所能抓到的最大精灵数。相当于二维费用的01背包。最后按皮卡丘损失体力从小到大扫一下,为了找最优解时皮卡丘剩余体力的最大值。原创 2017-08-07 16:13:35 · 483 阅读 · 0 评论 -
bailian4122:切割回文(区间dp)
dp[i]表示把前i个都变成回文串最少需要切割的次数。每次枚举在j后面切一刀,暴力判断(j+1,i)是否是回文,如果是,那就是要切割dp[j]+1次。取最小即可。原创 2017-08-07 16:25:39 · 638 阅读 · 0 评论 -
hdu1712 ACboy needs your help(分组背包板子)
分组背包板子。 问题 有N件物品和一个容量为V的背包。第i件物品的费用是c[i],价值是w[i]。这些物品被划分为若干组,每组中的物品互相冲突,最多选一件。求解将哪些物品装入背包可使这些物品的费用总和不超过背包容量,且价值总和最大。 算法 这个问题变成了每组物品有若干种策略:是选择本组的某一件,还是一件都不选。也就是说设f[k][v]表示前k组物品花费费用v能取得的最大权值,则有:原创 2017-08-07 16:34:47 · 387 阅读 · 0 评论 -
P1064 金明的预算方案【2006提高】(背包)
v[i][0]主件,v[i][1]附件1,v[i][2]附件2.每次决策时最多四种。转化为01背包。原创 2017-07-31 16:22:13 · 446 阅读 · 0 评论 -
poj3461 Oulipo(KMP)
求单词W在文本T中的出现次数。KMP裸题。#include #include #define N 1000005#define M 10005;char s[N],t[N];int n,m,fail[N];inline void getfail(){ int k=0;fail[1]=0; for(int i=2;i<=m;++i){ while(k&&t[k+1]!=t[i原创 2017-07-23 14:54:33 · 389 阅读 · 0 评论 -
poj3080 Blue Jeans(后缀数组+二分答案)
和poj3450一模一样。。双倍经验,嗯,很好。#include #include #define N 10000int mm,m,n,ansl=0,a[N],id[N],tst;int rank[N<<1],rank1[N],tmp[N],count[N],sa[N],h[N];inline int min(int x,int y){return x<y?x:y;}inline原创 2017-07-19 15:59:53 · 379 阅读 · 0 评论 -
poj3693(后缀数组+lcp+rmq)
求循环节个数最大的子串。先穷举长度L,然后求长度为L 的子串最多能连续出现几次。首先连续出现1 次是肯定可以的,所以这里只考虑至少2 次的情况。假设在原字符串中连续出现2 次,记这个子字符串为S,那么S 肯定包括了字符r[0], r[L], r[L*2],r[L*3], ……中的某相邻的两个。所以只须看字符r[L*i]和r[L*(i+1)]往前和往后各能匹配到多远,记这个总长度为K,那原创 2017-07-18 18:56:12 · 769 阅读 · 0 评论 -
poj3294 Life Forms(后缀数组+二分答案)
求在≥k个串中出现过的最长子串.还是先都连起来,用特殊字符隔开,然后二分答案,按h分组,在一组内统计出现过的子串,满足条件就更新,注意可能有多个子串满足条件,按照顺序存下来就好了。大坑点见注释。(有人就拿char过了,很神。)#include #include #define N 102000int s[N];bool blank=0,vis[110];int belong[N],n原创 2017-07-17 21:38:55 · 423 阅读 · 0 评论 -
poj1743 Musical Theme(后缀数组+二分答案)
都做个差值,就解决了转调问题,然后就是求最长不重叠重复子串。二分答案即可。判断不重叠:按h分组后,记录一组中的最小id--mn和最大id--mx,if(mx-mn>=x)即存在不重叠的。#include #include #define N 20005inline int min(int x,int y){return x<y?x:y;}inline int max(int x,i原创 2017-07-17 21:33:06 · 388 阅读 · 0 评论 -
poj3450 Corporate Identity(后缀数组+二分答案)
题意:求多个串的最长公共子串把所有串都接在一起。。用特殊字符隔开。然后和两个串的一样,二分答案,每次判断这个长度是否可行。(分组,一组中出现在所有串中即满足)我以前写的SA太弱了。。还TLE了。。改进了一下下。#include #include #define N 805000int mm,m,n,ansl=0,a[N],id[N];int rank[N<<1],rank1原创 2017-07-17 21:27:33 · 592 阅读 · 0 评论 -
poj2774 Long Long Message(后缀数组)
很简单的后缀数组,求两个串的最长公共子串。把这两个串,用特殊字符隔开连在一起,更新合法的最大公共前缀即可。原创 2017-07-17 15:15:08 · 366 阅读 · 0 评论 -
poj3415Common Substrings(后缀数组+单调栈)
题目大意:给两个字符串,求所有满足 长度大于等于k的公共子串 的对数。思路:基本的,计算A 的所有后缀和B 的所有后缀之间的最长公共前缀的长度,把最长公共前缀长度不小于k 的部分全部加起来。(显然会TLE到死),所以我们把这两个串连起来(中间用特殊字符隔开),根据h数组进行分组,保证一组内字符串之间lcp都是大于等于k的。接下来的工作便是快速的统计每组中后缀之间的最长公共前缀之和。扫描一遍原创 2017-07-17 14:36:08 · 400 阅读 · 0 评论 -
hdu4763 Theme Section(kmp)
题目大意:求最长的子串E,它既是串s的前缀又是后缀,还在串s的中间出现过(不能重叠)。直接从fai[len]开始枚举,在中间进行匹配,成功即可输出。#include #include #define N 1000010int tst,fail[N],m;char s[N];inline void getfail(){ int k=0;fail[1]=0; for(int i=原创 2017-07-23 23:34:46 · 340 阅读 · 0 评论 -
poj2752 Seek the Name, Seek the Fame(kmp)
从len开始,每一个fail[len]都可以。。不过要倒着输出。。原创 2017-07-28 22:26:42 · 287 阅读 · 0 评论 -
CEOI 2004 two 锯木厂(cogs)(斜率优化)
Description 从山顶上到山底下沿着一条直线种植了n棵老树。当地的政府决定把他们砍下来。为了不浪费任何一棵木材,树被砍倒后要运送到锯木厂。 木材只能按照一个方向运输:朝山下运。山脚下有一个锯木厂。另外两个锯木厂将新修建在山路上。你必须决定在哪里修建两个锯木厂,使得传输的费用总和最小。假定运输每公斤木材每米需要一分钱。 你的任务是编写一个程序,从输入文件中读入树的个数和原创 2017-08-05 20:37:20 · 700 阅读 · 0 评论 -
poj2406 Power Strings(kmp求循环节)
题目大意:求串s的最小循环节。用kmp处理出fail数组,len%(len-fail[len])如果为0,那么存在循环节,长度为len-fail[len],画一下图就可以自己证明啦#include #include #define N 1000010int fail[N],m;char s[N];inline void getfail(){ int k=0;fail[1]=0;原创 2017-07-24 14:02:49 · 505 阅读 · 0 评论 -
hdu4300 Clairewd’s message(KMP)
这题描述简直惊人。其实就是说先给你一个密码表。然后给你一个不一定完整的串。原串满足前一半是密码,后一半是明码。要求你最小的补全这个串。首先我们要明确:设给的串长度为len,则1...(len+1)/2的字母一定是密码。我们可以把这一部分作为模式串,去匹配后面的串。(当然因为我们假定后面的串都是明码,所以我们要把后面的串翻译成密码来匹配)。我们假设最后一位匹配到了模式串的第k位。则说明1..len-原创 2017-07-24 15:13:09 · 739 阅读 · 0 评论