cstring

Cat VS Dog HDU

妖精的绣舞 提交于 2020-11-19 02:52:30
Cat VS Dog Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 125536/65536 K (Java/Others) Total Submission(s): 4383 Accepted Submission(s): 1602 Problem Description The zoo have N cats and M dogs, today there are P children visiting the zoo, each child has a like-animal and a dislike-animal, if the child's like-animal is a cat, then his/hers dislike-animal must be a dog, and vice versa. Now the zoo administrator is removing some animals, if one child's like-animal is not removed and his/hers dislike-animal is removed, he/she will be happy. So the administrator wants to know which animals he

AC自动机

南笙酒味 提交于 2020-11-19 00:15:20
本来是早就该学的知识点了,但是拖了好长时间最近在重新捡起来。。。 【AC自动机???自动AC机???】 刚学OI的时候,就听到学长说AC自动机,第一次听到这个名字还以为只是开玩笑说用来自动A题的BUG。。。(相信总会有人和我想法是一样的) AC自动机就是字典树和KMP算法的结合,KMP实现的是单模匹配,也就是一个模式串与文本串进行匹配,但是如果我们有很多模式串怎么办呢? 这时我们就要引入字典树(发现树结构在OI 学习中贼优越的样子) 字典树就是一棵可以表示所有出现单词的树,就像字典一样可以进行单词的查询!!!这样就可以实现多模匹配。 但是要是我们一个个跳着来匹配字符那就GG了,和单模匹配一样的暴力,所以我们就要用KMP的失配指针来优化,定义失配指针为fail 首先我们来看看字典树是怎么建立的(如:AAC,CAA,CAC,BA) 那么加上其失配指针后: 这就是将序列上的KMP变成了树上的AC自动机了 !!! 接下来我们来看看AC自动机怎么实现的。。。 首先我们要建立一棵字典树,Trie树:(这应该是基本操作,不会的就要看看字典树了) 1.存储结构 1 struct sd{ 2 int son[ 30 ],end,fail;// 每个节点的下一个字符对应的节点,如果当前节点是一个单词的结尾那就记下来,失配指针 3 }trie[ 20005 ]; 4 char txt[ 1000005

【USACO习题】牛的旅行

眉间皱痕 提交于 2020-11-17 05:50:55
这道题在洛谷上的链接: https://www.luogu.org/problemnew/show/P1522 真心很无语,怎么会有这么奇怪的题。。。呃呃,题解。大家的做法几乎是一样的,我都不能理解,只有一个人的做法和我想的一样,可是很麻烦。 大家基本都是用Floyd求出每个点所能到达的最远的最短路,设为md[i],枚举不连通的两个结点i和j,求出最小的md[i]+md[j]+dis[i][j](dis[i][j]指两点间距离)。这还不算什么,更坑的是,又求出最大的md[i],将其与min(md[i]+md[j]+dis[i][j])比较,较大的为答案,说是什么将两个牧场连通后,直径如果要经过新路,可能还比原来牧场的直径小,这个很好理解,可是为什么要和所有牧场的直径比较?不应该是求max(dd[i],dd[j],md[i]+md[j]+dis[i][j])吗(dd[i]是指i所在连通块的直径)?然后最小的那个就是答案。 好吧,其实我一直没读懂题。 题目里面说的,刚好有两个牧场(论分不清举例与题目要求的后果)。 这样的话,第一种相对简单的方法就对了。 1 #include<cstdio> 2 #include<cmath> 3 #include<cstring> 4 #include<algorithm> 5 using namespace std; 6 const int maxn

线性DP详解

二次信任 提交于 2020-11-16 06:08:56
顾名思义,线性DP就是在一条线上进行DP,这里举一些典型的例子。 LIS问题(最长上升子序列问题) 题目 给定一个长度为N的序列A,求最长的数值单调递增的子序列的长度。 上升子序列B可表示为B={A k 1 , A k 2 ,···,A kp },其中k 1 <k 2 <···<k p 。 解析 状态:F[i]表示以A[i]为结尾的最长上升子序列的长度,边界为f[0]=0。 状态转移方程:F[i]=max{F[j]+1}(0≤j<i,A[j]<A[i])。 答案显然为max{F[i]}(1≤i≤N)。 事实上,无论是上升、下降还是不上升等等此类问题,代码都是相似的,唯一的区别只是判断的符号更改罢了。 Code #include <iostream> using namespace std; int n,a[ 100 ],f[ 100 ],maxn; int main() { f[ 0 ]= 0 ; cin >> n; for ( int i= 1 ;i<=n;i++ ) { cin >> a[i]; for ( int j= 1 ;j<n;j++ ) if (a[j]<a[i]) f[i]=max(f[i],f[j]+ 1 ); maxn = max(maxn,f[i]); } cout << maxn; return 0 ; } View Code LCS问题(最长公共子序列)

浅说——树形DP

余生长醉 提交于 2020-11-15 07:45:46
啊!DP! 顾名思义,树形DP就是 在树上所做的动态规划 。我们一般所做的动态规划多是 线性 的,线性DP我们可以从前向后或从后向前两种方法,不妨类比一下,在树上我们同样可以有两种方法,从 根向树叶 或者从 树叶向根 。从根向树叶传值的题不多见,而从叶向根传送值的题较多,下面我们主要来分析这种题。 luogu1352没有上司的舞会 分析: 把该题抽象到一颗树中,设i的下属就是他的儿子,则有两种情况: 如果i参加,他的儿子就不能参加。 如果i不参加,他的儿子可参加可不参加。 所以设f[i][1]表示i参加,f[i][0]表示i不参加,则有 f[i][ 0 ]+=max(f[j][ 0 ],f[j][ 1 ]); f[i][ 1 ]+=f[j][ 0 ]+w[i]; // j是i的儿子 所以 ans=max(f[i][ 1 ],f[i][ 0 ]) // 最大快乐指数 得到基础代码:(很粗略,不过好懂) #include<cstdio> #include <iostream> using namespace std; const int maxn= 6005 ; int f[maxn][ 2 ],n,r[maxn]; int son[maxn][maxn],tot[maxn]; int vis[maxn]; int end; void tree_dp( int x) { for (

高效自动化运维工具 Clip | 介绍篇

允我心安 提交于 2020-11-12 09:00:19
本文根据高效运维系列微信群的群友文章整理并发布。“高效运维”公众号作为本系列群的官方唯一公众号,原创并独家首发。 欢迎关注“高效运维”公众号,以免费参加「运维讲坛」每月一次的线下交流活动;并抢先赏阅干货满满的各种原创文章(详见文末)。 编辑 徐凯强@和信(整理) 作者介绍 王冬生 腾讯高级工程师,《Puppet权威指南》作者 引子 IP数字不容易记忆,所以聪明的人类发明了DNS。DNS把不容易记忆的数字,改为容易记忆的一串有规则的域名,域名又可以解析相应的IP,基于此思路,我们开发了近似 DNS 工具的名字服务系统。 在公司内部希望通过名字服务系统在 CMDB 基础之上把不同的业务(cpu、内存、磁盘和网卡)“夹在一起”,对于上层可以实现资源互补,对于下层可以方便核算业务成本,所以这就是CLIP(夹子)的由来了。 Clip 简介 Clip是一款自动化运维工具,适用于海量服务器的管理场景,可以降低系统误操作风险,提高工作效率。 其将传统的 IP 管理纬度替换为String管理纬度的管理方式,使海量运维变得更加便捷、可靠与高效。 Clip是 C/S 架构,它将IP关系保存在 Server 端,Client 端可以下载 SDK,通过 SDK 遍历 Server 端的 IP 与模块关系等,并在本地对获取的 IP 模块关系进行重新的组织与编排,这就是Clip。 Clip还提供了远程命令

【FCS NOI2018】福建省冬摸鱼笔记 day1

半世苍凉 提交于 2020-11-11 08:25:38
省冬的第一天。 带了本子,笔,一本《算法导论》就去了。惊讶于为什么同学不带本子记笔记。 他们说:“ 都学过了。 ”,果然这才是巨神吧。 第一天:数论,讲师:zzx 前几页的课件挺水,瞎记了点笔记。后面直接就讲了两道题,我就没想出来,真的菜。 然后学了波原根,又听不太懂。 莫比乌斯反演,又听不太懂。然而我自己瞎推式子好像就能反演出来,没想法XD。 杜教筛,又听不太懂。 线性代数,zzx干脆不讲了,没想法。反正也不是数论范畴。 第一天的早晨就这么过去了, @qrc 去AMC10了,没想法。 中午划水 下午毒瘤题开始做了,福一中的题面就是好看。 T1正解洲阁筛,我们都是分段打表的XD。——100 T2瞎推后就变成二维数点cdq分治了,没想法。——40 T3就是剧毒,处理表达式还要推式子算组合数,没想法。——0 结果 @lh 和 @qrc 居然就比我高了3分,没想法。 【T1】 题面:计算[l,r]中所有合数的最大真因数之和,对于一个合数,其最大真因数为它的正因数中除了它本身最大的一个。 题解:洲阁筛都没听懂。我的做法是:对于\(r-l\leq 5,000,000\)的数据,可以处理\(\sqrt{r}\)中的质数,把\([l,r]\)中的数筛出来。 对于更大的数据,分段打表即可。 1 #include<cstdio> 2 #include<algorithm> 3 #include

区间内的真素数

时光毁灭记忆、已成空白 提交于 2020-11-11 04:33:26
11:区间内的真素数 找出正整数 M 和 N 之间(N 不小于 M)的所有真素数。 真素数的定义:如果一个正整数 P 为素数,且其反序也为素数,那么 P 就为真素数。 例如,11,13 均为真素数,因为11的反序还是为11,13 的反序为 31 也为素数。 输入 输入两个数 M 和 N,空格间隔,1 <= M <= N <= 100000。 输出 按从小到大输出 M 和 N 之间(包括 M 和 N )的真素数,逗号间隔。如果之间没有真素数,则输出 No。 样例输入 10 35 样例输出 11,13,17,31 #include <iostream> #include <cstring> #include <algorithm> #include < string > #include <cmath> using namespace std; int prime( int ); int main() { int m,n,flag= 0 ,save= 0 ; string k; cin >>m>> n; for ( int i=m;i<=n;i++ ) { if (prime(i)== 1 ) { k = to_string(i);  //把i转为字符串 reverse(k.begin(), k.end());  //反转 save = stoi(k);   if (prime

poj1417(带权并查集+背包DP+路径回溯)

守給你的承諾、 提交于 2020-11-10 07:37:45
题目链接:http://poj.org/problem;jsessionid=8C1721AF1C7E94E125535692CDB6216C?id=1417 题意:有p1个天使,p2个恶魔,天使只说真话,恶魔只说假话。问n句话,问x:y是否为天使,x回答yes或no,分别表示是或否,问能否确认为天使的人的编号(1..p1+p2),若能按顺序1输出,否则输出no。 思路: 看到带权并查集的题首先考虑到向量,先分析一下,不访设x->y表示x说y是什么,0表示天使,1表示是恶魔,枚举一下会发现x->y=0也表示x y同类,=1表示x y异类。并且x->z=(x->y)^(y->z)。这样就很清晰了,我们使用并查集将有关系的人并起来,并得到每个人与其祖先的关系,这样之后就会得到一些集合,每个集合有两类人。我想到这了就不知道怎么做了,因为我是在刷bin巨并查集专题看到的这题,我的潜意识就是怎么用并查集去解决这个问题,所以我一直在想是不是有其他的并查集的方法。看了别人的博客才恍然大悟之后就是一个完全背包的题了啊。还是太年轻了,思维应该开阔些,不能局限在一种思维上去想怎么做题。 回到题目,利用并查集得到这些集合比较简单,稍微熟悉并查集都能想到,接下来的背包DP和路径回溯才是这道题的核心。先遍历一遍用r[i]表示第i个集合的祖先,用a[i][0]表示第i个集合与祖先同类的人数,用a[i][1

UVA12558 Egyptian Fractions (HARD version)(埃及分数)

。_饼干妹妹 提交于 2020-11-10 05:14:59
传送门 题目大意 给出一个真分数 a/b,要求出几个互不相同的埃及分数(从大到小),使得它们之和为 a/b (埃及分数意思是分子为1的分数,详见 百度百科 ) 如果有多组解,则分数数量少的优先 如果分数数量一样则 分母最大的要尽量小,如果最大的分母同样大,则第二大的分母尽量小,以此类推 为了加大难度,会给出k个不能作为分母的数 (2<=a,b<=876,k<=5 并且 a,b 互质) 首先想的是数论,但是呢 推不出来... 然后发现a,b好像不大 貌似可以搜索 但是呢 不知道上界... 那就迭代加深搜索呗 然后想想怎么剪枝 如果知道 a/b,要怎么求出最小 k 使 1/k < a/b 呢(注意符号) 易知 a/ b 为真分数 ,a,b,k均为整数 所以 a < b 所以必定有整数 x,y 使得 x *a+y=b 且y< a 所以可得 int (b/a)= int ( (x*a+y) /a )= int (x*a/a)+ int (y/a) = x 因为 int (b/a)<=b/a, int (b/a)= x 所以 x+ 1 > b/ a , 所以 int(b/a)+1>b/a, 所以1 /(x+ 1 ) < a/ b 又 1 / int (b/a)= 1 /x >=a/ b 所以 x +1就是最小的 k 使得 1 /k < a/ b 所以 k = int (b/a) + 1