<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>string on The Site of laekov</title>
    <link>/tags/string/</link>
    <description>Recent content in string on The Site of laekov</description>
    <generator>Hugo -- gohugo.io</generator>
    <language>en</language>
    <copyright>&amp;copy; laekov</copyright>
    <lastBuildDate>Fri, 10 Apr 2015 22:50:06 +0000</lastBuildDate><atom:link href="/tags/string/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>bzoj3940 [Usaco2015 Feb]Censoring</title>
      <link>/oi/dbimport_216/</link>
      <pubDate>Fri, 10 Apr 2015 22:50:06 +0000</pubDate>
      
      <guid>/oi/dbimport_216/</guid>
      <description>自从会了sam,似乎已经不知道acam该怎么写了ovo
这个题就是强行用ac自动机记录匹配到某个位置的时候的状态.然后如果走到一个终态的话就可以强行删掉一段,然后把当前状态变为上一个状态.
最初没有想到有可能会连续删除,于是挂了很久.最后用官网上的数据还是过不了第9个点,然后交bzoj居然过了.好神奇.我猜想是迅雷挂了hhh毕竟usaco的数据用wget根本搞不下来好伤心.
所以我还是太弱ovo</description>
    </item>
    
    <item>
      <title>bzoj2251 [2010Beijing Wc]外星联络</title>
      <link>/oi/dbimport_132/</link>
      <pubDate>Mon, 06 Apr 2015 13:51:17 +0000</pubDate>
      
      <guid>/oi/dbimport_132/</guid>
      <description>后缀数组的基础题ovo好久没写sa了还自己yy了半天ovo
为啥感觉每次写sa写得都不一样ovo
求出height数组之后,如果一个位置的height大于上一个位置的,那么高出来的这一截都是新的一个答案.那么直接朴素地去找它出现了多少次就好了.我相信出题人没有办法构造数据把我卡到三方.
所以各种题都要再复习一下ovo</description>
    </item>
    
    <item>
      <title>bzoj3238 [Ahoi2013]差异</title>
      <link>/oi/dbimport_184/</link>
      <pubDate>Fri, 03 Apr 2015 10:39:33 +0000</pubDate>
      
      <guid>/oi/dbimport_184/</guid>
      <description>考试的时候do big die去刷bzoj.大概下午会hug zero.
sam的第二题.其实这个玩意是应该用sa做的,不过现在我觉得sa没有sam简单.虽然sam的构造和性质还是一团大雾.
这个题可以做出原串的后缀树,然后在上面dp一下.每个点对答案的贡献为任意两个不在同一子树的终态对数*深度.
然后倒过来建sam,它的parent树就是原串的后缀树.虽然我还没有成功理解这个东西.
然后坑了一会的一件事情是新建的nq节点的right集合为空.因为它只是一个扩展点,但是不是一个接受态ovo
我还是太弱啊怎么办.</description>
    </item>
    
    <item>
      <title>bzoj2806 ctsc2012 Cheat</title>
      <link>/oi/dbimport_161/</link>
      <pubDate>Wed, 25 Mar 2015 20:13:37 +0000</pubDate>
      
      <guid>/oi/dbimport_161/</guid>
      <description>我的SAM第一题。按照惯例几乎是照着std抄的OVO。本来以为是要在SAM上DP，后来发现好像是并列的，于是比较开心。
SAM这个东西主要就是用来匹配子串用的。建法详见clj的课件，然后现在我还处于消化状态中。
SAM匹配多个串的话也比较好弄，直接在串末再加一个字符集里没有的元素就好了。
现在假设已经用SAM匹配出了第i个位置往左ml[i]个位置都是可以匹配的，那么可以二分一个答案，然后用单调队列来DP判断。写法比较简单，虽然我急着去写SAM所以这部分也是蒙过去的。
然后网上的2个std就有2种不同的答案还和我不一样。最后还是wd学长的代码靠谱orz。
现在我可以说我是写过SAM的人了哈哈。</description>
    </item>
    
    <item>
      <title>BZOJ2342 [Shoi2011]双倍回文</title>
      <link>/oi/i11rimport_039/</link>
      <pubDate>Sun, 22 Feb 2015 16:52:41 +0000</pubDate>
      
      <guid>/oi/i11rimport_039/</guid>
      <description>&amp;lt;div class=&amp;quot;post_brief&amp;quot;&amp;gt;&amp;lt;p&amp;gt; 久了不写manacher又手生了只好抄红书了。&amp;lt;/p&amp;gt; &amp;nbsp;
后面的过程就是对每个位置i找一个最远的位置j满足j在i为中心的回文子串的一半以内且j最小。然后直接拿个set就能搞定。
&amp;nbsp;
#include &amp;lt;cstdio&amp;gt; #include &amp;lt;cstring&amp;gt; #include &amp;lt;algorithm&amp;gt; #include &amp;lt;set&amp;gt; using namespace std;
const int maxn = 500009;
char a[maxn]; int d[maxn &amp;lt;&amp;lt; 1], n;
void manacher() { d[0] = 1; for (int i = 1, j = 0; i &amp;lt; (n &amp;lt;&amp;lt; 1) - 1; ++ i) { int p(i &amp;gt;&amp;gt; 1), q(i - p), r(((j + 1) &amp;gt;&amp;gt; 1) + d[j] - 1); if (r &amp;lt; q) d[i] = 0; else d[i] = min(r - q + 1, d[(j &amp;lt;&amp;lt; 1) - i]); while (p - d[i] &amp;gt;= 0 &amp;amp;&amp;amp; q + d[i] &amp;lt; n &amp;amp;&amp;amp; a[p - d[i]] == a[q + d[i]]) ++ d[i]; if (q + d[i] - 1 &amp;gt; r) j = i; } }</description>
    </item>
    
    <item>
      <title>BZOJ2565 最长双回文串</title>
      <link>/oi/lofterimport_033/</link>
      <pubDate>Sat, 20 Dec 2014 23:09:18 +0000</pubDate>
      
      <guid>/oi/lofterimport_033/</guid>
      <description>以前觉得不会，仔细想想觉得还是挺水。
manacher找出所有中心回文串，然后用单调队列扫一下每个位置往左最长和往右最长就行。找位置比较烦不过还是比较好写的。
重点是写出了在windows下拿for循环对拍，虽然异常丑。
#include &amp;lt;cstdio&amp;gt;
#include &amp;lt;cstring&amp;gt;
#include &amp;lt;algorithm&amp;gt;
using namespace std;
const int maxn = 200009;
int n, l[maxn], q[maxn], vx[maxn], vy[maxn];
char a[maxn];
void manacher()&amp;nbsp;{
l[0]&amp;nbsp;= 1;
for (int i = 1, j = 0; i &amp;lt;&amp;nbsp;(n&amp;nbsp;&amp;lt;&amp;lt; 1)&amp;nbsp;- 1;&amp;nbsp;++ i)&amp;nbsp;{
int r =&amp;nbsp;((j&amp;nbsp;+ 1)&amp;nbsp;&amp;gt;&amp;gt; 1)&amp;nbsp;+ l[j]&amp;nbsp;- 1;
int p = i &amp;gt;&amp;gt; 1, q = i - p;
l[i]&amp;nbsp;=&amp;nbsp;(r &amp;gt;= q)&amp;nbsp;? min(r - q + 1, l[(j &amp;lt;&amp;lt; 1)&amp;nbsp;- i])&amp;nbsp;: 0;</description>
    </item>
    
    <item>
      <title>BZOJ2105 增强型LCP</title>
      <link>/oi/lofterimport_037/</link>
      <pubDate>Wed, 17 Dec 2014 16:03:47 +0000</pubDate>
      
      <guid>/oi/lofterimport_037/</guid>
      <description>最初以为是splay维护Hash的简单题。顺手开心地敲了个splay还是指针版的。
然后发现tle了。
然后知道了可以暴力重新建串。
然后拿splay暴力重新建串。
然后又tle了。
然后不得已改成了随机线性存取表，过之。
我还是太naive了啊。
#include &amp;lt;cstdio&amp;gt;
#include &amp;lt;cstring&amp;gt;
#include &amp;lt;algorithm&amp;gt;
using namespace std;
typedef unsigned long long qw;
#define _l (long long int)
const int maxn = 200009;
const int base = 233;
struct str {
char a[maxn];
int len;
inline str()&amp;nbsp;{
len = 0;
}
inline void read()&amp;nbsp;{
scanf(&amp;quot;%s&amp;quot;, a + 1);
len = strlen(a + 1);
}
inline char operator [](const int&amp;amp; x) const {</description>
    </item>
    
    <item>
      <title>BZOJ1692 [Usaco2007 Dec]队列变换</title>
      <link>/oi/lofterimport_039/</link>
      <pubDate>Tue, 16 Dec 2014 19:34:28 +0000</pubDate>
      
      <guid>/oi/lofterimport_039/</guid>
      <description>最初以为是水题，直接写个dq交上去不对。
看了下题解才知道是后缀数组。好久不写都快不会写了。
把原串倒过来扔一起排一下就行了。
#include &amp;lt;cstdio&amp;gt;
#include &amp;lt;cctype&amp;gt;
#include &amp;lt;cstring&amp;gt;
#include &amp;lt;algorithm&amp;gt;
using namespace std;
const int maxn = 60009;
int n;
int sa[maxn], rk[maxn], ro[maxn], w[maxn], o[maxn];
char a[maxn];
void sufixArray(int n)&amp;nbsp;{
memset(w, 0, sizeof(w));
for (int i = 0; i &amp;lt; n;&amp;nbsp;++ i)
++ w[(int)a[i]];
for (int i = 1; i &amp;lt; 123;&amp;nbsp;++ i)
w[i]&amp;nbsp;+= w[i - 1];
for (int i = 0; i &amp;lt; n;&amp;nbsp;++ i)
sa[-- w[(int)a[i]]]&amp;nbsp;= i;</description>
    </item>
    
    <item>
      <title>BZOJ2795 A Horrible Poem</title>
      <link>/oi/lofterimport_043/</link>
      <pubDate>Sat, 13 Dec 2014 20:41:53 +0000</pubDate>
      
      <guid>/oi/lofterimport_043/</guid>
      <description>今天上课讲的题。
做法就直接枚举约数，或者说分解质因数。后者可以预处理到log。
判循环也比较开心。直接用一些奇奇怪怪的字符串的性质就好了。
看来字符串很博大精深啊。
#include &amp;lt;cstdio&amp;gt;
#include &amp;lt;cctype&amp;gt;
#include &amp;lt;cstring&amp;gt;
#include &amp;lt;algorithm&amp;gt;
using namespace std;
typedef unsigned long long qw;
typedef pair &amp;lt;int, qw&amp;gt; hstrv;
#define _l (long long int)
int _d_;
#define readInt(_x_)&amp;nbsp;{&amp;nbsp;\
int&amp;amp; _s_ = _x_;&amp;nbsp;\
while (!isdigit(_d_&amp;nbsp;= getchar()));&amp;nbsp;\
_s_ = 0;&amp;nbsp;\
while ((_s_&amp;nbsp;= _s_ * 10 + _d_ - 48), isdigit(_d_ = getchar()));&amp;nbsp;\
}
const int maxn = 500009;
const int base = 257;
const int hmod = 1000000093;</description>
    </item>
    
  </channel>
</rss>
