cstring

hihocoder 后缀自动机五·重复旋律8 求循环同构串出现的次数

白昼怎懂夜的黑 提交于 2020-05-04 00:30:22
描述 小Hi平时的一大兴趣爱好就是演奏钢琴。我们知道一段音乐旋律可以被表示为一段数构成的数列。 小Hi发现旋律可以循环,每次把一段旋律里面最前面一个音换到最后面就成为了原旋律的“循环相似旋律”,还可以对“循环相似旋律”进行相同的变换能继续得到原串的“循环相似旋律”。 小Hi对此产生了浓厚的兴趣,他有若干段旋律,和一部音乐作品。对于每一段旋律,他想知道有多少在音乐作品中的子串(重复便多次计)和该旋律是“循环相似旋律”。 解题方法提示 × 解题方法提示 小Hi:我们已经对后缀自动机比较熟悉了,今天我们再来道稍有难度的题。 小Ho:好!这道题目让我们求的是若干串在另一个长串S中各自作为子串出现的次数,只是匹配的方式从完全相等变成了“循环同构”。 小Hi:没错!如果匹配方式是完全相等的话,本题就可以使用AC自动机或者 trie图 完美的解决。 小Ho:既然这个问题也和子串有关系,那么不妨试试后缀自动机。 小Hi:对。和上一期一样,你可以先想想如果询问只有一个串T应该怎么做。 小Ho:嗯,那自然就考虑所有T的循环同构的串在长串S中出现的次数。 小Hi:没错。循环同构有点麻烦,如果我们枚举与T循环同构的串,再依次判断是否在S中出现过。那复杂度至少是O(length(T)^2)的了。 小Ho:恩。比如T="abcd"的话,我们要判断4个串"abcd", "bcda", "cdab", "dabc

hihoCoder #1465 : 后缀自动机五·重复旋律8

假装没事ソ 提交于 2020-05-03 23:51:02
http://hihocoder.com/problemset/problem/1465 求S的循环同构串在T中的出现次数 将串S变成SS 枚举SS的每个位置i,求出以i结尾的SS的子串 与 T的最长公共子串 若长度>=|S|,说明以i结尾的S的循环同构串在T中出现过 假设最后匹配i到达了后缀自动机的a节点 沿着a的parent树以直向上走,走到离根最近的 匹配长度>=|S|的节点b b的在parent树中的子树 叶子节点个数 即为这个以i结尾的循环同构串在T中的出现次数 #include<cstdio> #include <cstring> #include <iostream> using namespace std; #define N 1000001 char s[N<< 1 ]; int ch[N<< 1 ][ 26 ],tot= 1 ; int last= 1 ,p,q,np,nq; int fa[N<< 1 ],len[N<< 1 ]; int r[N<< 1 ]; int v[N<< 1 ]; int sa[N<< 1 ]; int use[N<< 1 ]; int now,now_len; long long ans; void extend( int c) { len[np =++tot]=len[last]+ 1 ; for (p=last;p && !ch

2018山东省ACM省赛 G题Games

安稳与你 提交于 2020-05-03 23:29:16
时间限制: 2 Sec 内存限制: 128 MB 提交: 70 解决: 17 [提交][状态][讨论版][命题人:admin] 题目描述 Alice and Bob are playing a stone game. There are n piles of stones. In each turn, a player can remove some stones from a pile (the number must be positive and not greater than the number of remaining stones in the pile). One player wins if he or she remove the last stone and all piles are empty. Alice plays first. To make this game even more interesting, they add a new rule: Bob can choose some piles and remove entire of them before the game starts. The number of removed piles is a nonnegative integer, and not greater than a

bzoj5164: 餐厅计划问题(三分+贪心)

谁说我不能喝 提交于 2020-05-03 22:11:15
  网络流经典题里餐巾计划的加强版...天数变成了$10^5$,那就不能用费用流做了...   考虑费用流的时候,单位费用随流量的增加而减少,也就是说费用其实是个单峰(下凸)函数。   那么可以三分要买的餐巾个数,求费用可以用贪心。   新买的没用就用新买的,否则能慢洗的慢洗,不能慢洗的拿最晚的快洗后可以当天用的去快洗。   有一个错误的贪心是慢洗和快洗的都拿最早的,这样可能会导致快洗的本来可以洗时间更晚一些的,却洗了比较早的餐巾,而这些餐巾本可以在接下来的一天里通过慢洗来省下更多的钱。 #include<iostream> #include <cstring> #include <cstdlib> #include <cstdio> #include <algorithm> #define ll long long using namespace std; const int maxn= 500010 , inf= 1e9; struct poi{ int tim, rest;}q1[maxn], q2[maxn], q3[maxn]; int d, n1, n2, c1, c2, tc, ans= inf; int t[maxn]; inline void read( int & k) { int f= 1 ; k= 0 ; char c= getchar(); while

CodeForces911D 逆序对

僤鯓⒐⒋嵵緔 提交于 2020-05-03 20:29:56
http://codeforces.com/problemset/problem/911/D 题意 给你一个长度为N的序列,有M次操作。每次翻转[l,r]的区间,每次操作后询问序列逆序对个数的奇偶性 很显然问题每次操作之后的变化数量只与区间内自身的逆序数对有关,比较麻烦的操作是翻转的操作。 但是本题的问题是逆序数对的奇偶性,事实上经过仔细的比较发现,整个序列翻转后的逆序数对与被翻转的区间内数字无关,只和区间长度有关。 区间(l,r)内所有数字的对数是(r - l + 1) * (r - l) / 2; 如果所有数字的对数是偶数, 不论区间内逆序数对数是偶数还是奇数,都不变(奇数变奇数,偶数变偶数)。 相反,数字对数是偶数,则不论如何都会改变。 #include <map> #include < set > #include <ctime> #include <cmath> #include <queue> #include <stack> #include <vector> #include < string > #include <cstdio> #include <cstdlib> #include <cstring> #include <sstream> #include <iostream> #include <algorithm> #include <functional

单源堆优化Dijkstra

时间秒杀一切 提交于 2020-05-03 19:21:16
那么就用堆优化的Dijkstra~~(迪杰克斯歘)~~ 关于什么是Dijkstra? 左转百度 但是我自己都觉得那个讲的太复杂,就简单的讲一下吧 Dijkstra不会死去的条件: 该有权图不含负权边时间复杂度为O(n^2) 介绍一下: Dijkstra类似于贪心 首先先确定一个源点(这里就是1号点),先把所有Dis(1,i)(i!=1)都定为INF,然后先遍历一遍,把与点1相连的点(即只用走一个连边)的点i的距离都第一次直接处理为Dis(1,i) 第二次遍历把与`Dis(1,i)<INF`的点有连接的点j的Dis处理为Dis(1,i,j)意为用i点的Dis来给j点附上Dis,可以说`Dis(1,j)=Dis(1,i)+Dis(i,j);` 之后我们重复第二次的操作,不过这次会多一种情况,即用Dis(j)来处理Dis(i),就是说这次遍历到j点的时候,如果有`Dis(1,j,i)<Dis(1,i)<INF`,我们就Dis(1,i)的值变为 `min(Dis(1,j),Dis(1,j)+Dis(j,i))` 遍历过后,如果仍有Dis(k)=INF的话,就证明点1无法到点k,所以我们只需要输出`-1`就可以了 那么什么是堆优化Dijkstra呢? 每次扩展一个距离最小的点,再更新与其相邻的点的距离。 如何寻找距离最小的点? 优化方案是建一个小根堆,小根堆里存储由当前结点更新距离的所有点

浙江大学第十九届图森未来杯大学生程序设计竞赛

微笑、不失礼 提交于 2020-05-02 19:59:38
赛后总结:  T:这是我们第二次集体去参加学校的比赛,总体来说比上一次去浙江中医药校赛成绩好一点,也算是看到了我们自己的进步?然后呢,今天比赛,我们分头看了三道签到题,E J G,然后彭彭和金姐飞快的A了起来,我。。。看E看了好几遍才看懂。因为太紧张了,所以看到别人A那么快,然后就很想快速读懂题意。然后就开始看别的,直到彭彭和我们说A有点像二分图匹配,然后就开始看A了,然后我们想了一下,m那么大不可能是二分图,就想别的办法。最后和金姐讲了我的思路,然后就开始操作。于是看起了B,接收到题目意思有点问题,想了快两个小时也没想出来。期间金姐也在疯狂A提交。崩溃啊。然后就看了C,这题也有很多读题误区,金姐开始写了。我再读了一遍B,发现题意和我之前想的不一样。。。。啊啊啊然后就和队友说了,我们就想板子模拟大数中。最后没时间了,啥都没做出来。赛后队内总结了经验,交流一下以后读题的分工,还是很有收获的一场比赛。emmm,加油吧。  J:今天前三题十分顺利,但是在A题上掉进了自己作的坑,疯狂WA,还好最后A出来了。C题感觉能写出来,可是时间不够了,哭~~~还是实力太弱了,继续努力,下次加油! P:看J时,浏览前几行后发现跟素数有关,数据范围还特别大就放弃了(其实真正的题目在最后三四行)翻了前面的题目。看了榜,发现J题A的很多,重新看回J题才发现真的是道水题,我就直接做了。接着,跟榜看了A

VC++编写简单串口上位机程序

落花浮王杯 提交于 2020-05-02 15:40:55
VC++编写简单串口上位机程序 VC++编写简单串口上位机程序 串口通信,MCU跟PC通信经常用到的一种通信方式,做界面、写上位机程序的编程语言、编译环境等不少,VB、C#、LABVIEW等等,我会的语言很少,C语言用得比较多,但是还没有找到如何用C语言来写串口通信上位机程序的资料,在图书管理找到了用VC++编写串口上位机的资料,参考书籍,用自己相当蹩脚的C++写出了一个简单的串口上位机程序,分享一下,体验一下单片机和PC通信的乐趣。 编译环境:VC++6.0 操作系统:VMWare虚拟出来的Windows XP 程序实现功能: 1、 PC初始化COM1口,使用n81方式,波特率57600与单片机通信。PC的COM口编号可以通过如下方式修改: 当然也可以通过上位机软件编写,通过按钮来选择COM端口号,但是此次仅仅是简单的例程,就没有弄那么复杂了。COM1口可用的话,会提示串口初始化完毕。否则会提示串口已经打开Port already open,表示串口已经打开,被占用了。 2、 点击开始转换,串口会向单片机发送0xaa,单片机串口中断接收到0xaa后启动ADC转换一次,并把转换结果ADCL、ADCH共两个字节的结果发送至PC,PC进行数值转换后在窗口里显示。(见文章末尾图) 3、 为防止串口被一只占用,点击关闭串口可以关闭COM1,供其它程序使用,点击后按钮变为打开串口

P4098 [HEOI2013]ALO

情到浓时终转凉″ 提交于 2020-05-02 10:20:25
最近这个家伙去哪了,为啥一直不更博客了呢?原来他被老师逼迫去补了一周的文化课, 以至于不会把班里的平均分拉掉太多 。好了,我们来看下面这道题目: P4098 [HEOI2013]ALO 题目描述 Welcome to ALO ( Arithmetic and Logistic Online)。这是一个 VR MMORPG, 如名字所见,到处充满了数学的谜题 现在你拥有 n 颗宝石,每颗宝石有一个能量密度,记为 ai,这些宝石的能量 密度两两不同。现在你可以选取连续的一些宝石(必须多于一个)进行融合,设 为 ai, ai+1, …, aj,则融合而成的宝石的能量密度为这些宝石中能量密度的次大值 与其他任意一颗宝石的能量密度按位异或的值,即,设该段宝石能量密度次大值 为 k,则生成的宝石的能量密度为 max{k xor ap | ap ≠ k , i ≤ p ≤ j} 现在你需要知道你怎么选取需要融合的宝石,才能使生成的宝石能量密度最 大 输入输出格式 输入格式: 第一行,一个整数 n,表示宝石个数 第二行,n 个整数,分别表示 a1 至 an,表示每颗宝石的能量密度,保证对于 i ≠ j 有 ai ≠ aj 输出格式: 输出一行一个整数,表示最大能生成的宝石能量密度 输入输出样例 输入样例#1: 5 9 2 1 4 7 输出样例#1: 14 首先关于异或和什么的问题

【GDOI2018】D1T2 密码锁(lock)

假如想象 提交于 2020-05-02 07:25:25
题目大意   给出n个数,每次选择任意一个区间加或减1,求最少多少次能在$mod m$意义下全变成0。 Solution   首先我们对于这n个数前后加个零,在$mod m$意义下差分一下。   $f[i]=(a[i]-a[i-1]+m)mod m$   于是区间加减1操作就转换成了在某一位加一,另一位减一。   容易发现,每个数只会加到m或者减到1,而不会有多次循环。   这样我们对差分序列排个序,在前半部分选择$l$减到1,后半部分选择$r$个加到n,($l+r=n$)   这题就没了。 AC Code #include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <cctype> using namespace std; #define MAXBUF 50000000 char buffer[MAXBUF]; int pos; inline void load(){ fread(buffer, 1 ,MAXBUF,stdin); pos = 0 ; } inline char gchar(){ return buffer[pos++ ]; } inline int rd(){ int ret= 0 ,f= 1 ; char c= gchar(); for (;!