??xml version="1.0" encoding="utf-8" standalone="yes"?>久久久91人妻无码精品蜜桃HD,久久久久免费看成人影片,亚洲国产精品人久久 http://m.shnenglu.com/ACflying/KNIGHT zh-cn Tue, 13 May 2025 15:02:09 GMT Tue, 13 May 2025 15:02:09 GMT 60 poj 3648 Wedding http://m.shnenglu.com/ACflying/archive/2009/06/07/86997.htmlKNIGHT KNIGHT Sun, 07 Jun 2009 09:19:00 GMT http://m.shnenglu.com/ACflying/archive/2009/06/07/86997.html http://m.shnenglu.com/ACflying/comments/86997.html http://m.shnenglu.com/ACflying/archive/2009/06/07/86997.html#Feedback 3 http://m.shnenglu.com/ACflying/comments/commentRss/86997.html http://m.shnenglu.com/ACflying/services/trackbacks/86997.html Wedding
Time Limit: 1000MS
Memory Limit: 65536K
Total Submissions: 821
Accepted: 249
Special Judge
Description
Up to thirty couples will attend a wedding feast, at which they will be seated on either side of a long table. The bride and groom sit at one end, opposite each other, and the bride wears an elaborate headdress that keeps her from seeing people on the same side as her. It is considered bad luck to have a husband and wife seated on the same side of the table. Additionally, there are several pairs of people conducting adulterous relationships (both different-sex and same-sex relationships are possible), and it is bad luck for the bride to see both members of such a pair. Your job is to arrange people at the table so as to avoid any bad luck.
Input
The input consists of a number of test cases, followed by a line containing 0 0. Each test case gives n , the number of couples, followed by the number of adulterous pairs, followed by the pairs, in the form "4h 2w" (husband from couple 4, wife from couple 2), or "10w 4w", or "3h 1h". Couples are numbered from 0 to n - 1 with the bride and groom being 0w and 0h.
Output
For each case, output a single line containing a list of the people that should be seated on the same side as the bride. If there are several solutions, any one will do. If there is no solution, output a line containing "bad luck".
Sample Input
10 6
3h 7h
5w 3w
7h 6w
8w 3w
7h 3w
2w 5h
0 0
Sample Output
1h 2h 3w 4h 5h 6h 7h 8h 9h
Source
Waterloo Local Contest , 2007.9.29
。。。。。。。。。。。。。。。。。。。?br />郁闷。。。。。。。。。。。。。。。。。?br />搞的一下午。。。。。。。。。。。。。。。错了Nơ。。。?br />题目很WS最后从M遍。。。。。。。。。终于读懂。。。。?br />饿死我了。。。。。。。。。。。。。。还不会(x)构图。。。。。?br />先吃饭,回来在搞。。。。。。。,今天p5道题q困难了。。。郁闗?br />--------------------------------------------------------------------------------------------------------------------------------------------------------------
2009.6.8 22:34
代码很丑不脓(chung)了,再有6分钟q灯了。。。。。h下想了一?x)感觉一h\是对的就是没有考虑0w-?h的这条边。。。?br />l果一改之。。。。。。。。。。AC
2009-06-08 22:33:58 AC旉 AC完了之后说了两个字“我日”耗费了两U钟。然后直接打开Blog。今晚终于搞出来? 感谢指出Bug的大牛?br />啊,自习(fn)了、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、?br /> ]]> poj 3678 Priest John's Busiest Day http://m.shnenglu.com/ACflying/archive/2009/06/07/86966.htmlKNIGHT KNIGHT Sun, 07 Jun 2009 02:39:00 GMT http://m.shnenglu.com/ACflying/archive/2009/06/07/86966.html http://m.shnenglu.com/ACflying/comments/86966.html http://m.shnenglu.com/ACflying/archive/2009/06/07/86966.html#Feedback 0 http://m.shnenglu.com/ACflying/comments/commentRss/86966.html http://m.shnenglu.com/ACflying/services/trackbacks/86966.html 开始的时候本以ؓ(f)不用拓扑Q而在见图的时候全部徏成无向图。。。。结果不a而喻 部分代码如下Q?br />#include < iostream > #include< stack > #include< vector > #define MAXN 2100 using namespace std; vector < int > v[MAXN],nv[MAXN],cont[MAXN]; int pre[MAXN],low[MAXN],id[MAXN]; int ans[MAXN],dfn[MAXN]; int cnt,scnt,n,m,N; stack < int > ST; struct NODE { int x,y; } arr[MAXN]; void Tarjan( int x) { int t,i; int min = low[x] = pre[x] = cnt ++ ; ST.push(x); for (i = 0 ;i < v[x].size();i ++ ) { t = v[x][i]; if (pre[t] ==- 1 )Tarjan(t); if (low[t] < min)min = low[t]; } if (min < low[x]) { low[x] = min; return ; } do { id[t = ST.top()] = scnt; low[t] = m;ST.pop(); } while (t != x); scnt ++ ; } int SCC() { scnt = cnt = 0 ; while ( ! ST.empty())ST.pop(); memset(pre, 0xff , sizeof (pre)); memset(low, 0 , sizeof (low)); for ( int i = 0 ;i < m;i ++ ) if (pre[i] ==- 1 )Tarjan(i); for ( int i = 0 ;i < m;i ++ ) cont[id[i]].push_back(i); return scnt; } void DFS( int k) { dfn[k] = cnt ++ ; for ( int i = 0 ;i < nv[k].size();i ++ ) { int w = nv[k][i]; if (dfn[w] ==- 1 )DFS(w); } ans[scnt ++ ] = k; } void ColDFS( int k) { dfn[k] = 2 ; for ( int i = 0 ;i < nv[k].size();i ++ ) { int w = nv[k][i]; if (dfn[w] ==- 1 )ColDFS(w); } } void GetOneAnswer() { memset(dfn, 0xff , sizeof (dfn)); for ( int i = 0 ;i < m;i ++ ) for ( int j = 0 ;j < v[i].size();j ++ ) { int x = id[i],y = id[v[i][j]]; if (x != y)nv[x].push_back(y); } cnt= scnt = 0 ; for ( int i = 0 ;i < N;i ++ ) if (dfn[i] ==- 1 )DFS(i); memset(dfn, 0xff , sizeof (dfn)); for ( int i = scnt - 1 ;i >= 0 ;i -- ) if (dfn[ans[i]] ==- 1 ) { int a = cont[ans[i]][ 0 ],b; if (a < n)b = a + n; else b = a - n; dfn[ans[i]] = 1 ; if (dfn[id[b]] ==- 1 )ColDFS(id[b]); } }void PRINTF() { printf( " YES\n " ); GetOneAnswer(); for ( int i = 0 ;i < n;i ++ ) { int x = arr[i].x,y = arr[i].y; int tx = arr[i + n].x,ty = arr[i + n].y; if (dfn[id[i]] == 2 )printf( " %02d:%02d %02d:%02d\n " ,x / 60 ,x % 60 ,y / 60 ,y % 60 ); else printf( " %02d:%02d %02d:%02d\n " ,tx / 60 ,tx % 60 ,ty / 60 ,ty % 60 ); } } void solve() { int i = 0 ; for (N = SCC();i < n;i ++ ) if (id[i] == id[n + i]) break ; if (i == n)PRINTF(); else printf( " NO\n " ); } ]]> poj 3207 Ikki's Story IV - Panda's Trick http://m.shnenglu.com/ACflying/archive/2009/06/06/86939.htmlKNIGHT KNIGHT Sat, 06 Jun 2009 12:12:00 GMT http://m.shnenglu.com/ACflying/archive/2009/06/06/86939.html http://m.shnenglu.com/ACflying/comments/86939.html http://m.shnenglu.com/ACflying/archive/2009/06/06/86939.html#Feedback 0 http://m.shnenglu.com/ACflying/comments/commentRss/86939.html http://m.shnenglu.com/ACflying/services/trackbacks/86939.html l果从读之后又因为界限Wa了一ơ。。。。晕 47ms比较慢,可能是用了STL的vector和stack的原因吧 部分代码如下#include < iostream > #include< stack > #include< vector > #define MAXN 1200 using namespace std; int pre[MAXN],low[MAXN],id[MAXN]; int cnt,scnt,n,N,M; vector < int > v[MAXN]; stack < int > ST; struct NODE { int x,y; } arr[MAXN]; void Tarjan( int x) { int t,i; int min = low[x] = pre[x] = cnt ++ ; ST.push(x); for (i = 0 ;i < v[x].size();i ++ ) { t = v[x][i]; if (pre[t] ==- 1 )Tarjan(t); if (low[t] < min)min = low[t]; } if (min < low[x]) { low[x] = min; return ; } do { id[t = ST.top()] = scnt; low[t] = n;ST.pop(); } while (t != x); scnt ++ ; } int SCC() { scnt = cnt = 0 ; memset(pre, 0xff , sizeof (pre)); memset(low, 0 , sizeof (low)); for ( int i = 0 ;i < n;i ++ ) if (pre[i] ==- 1 )Tarjan(i); return scnt; } ]]> 谈2—SAT问题 http://m.shnenglu.com/ACflying/archive/2009/06/06/86912.htmlKNIGHT KNIGHT Sat, 06 Jun 2009 07:00:00 GMT http://m.shnenglu.com/ACflying/archive/2009/06/06/86912.html http://m.shnenglu.com/ACflying/comments/86912.html http://m.shnenglu.com/ACflying/archive/2009/06/06/86912.html#Feedback 0 http://m.shnenglu.com/ACflying/comments/commentRss/86912.html http://m.shnenglu.com/ACflying/services/trackbacks/86912.html
2-SATQ?/strong>
1
2
-
SAT是2判定性问题,是一U特D的逻辑判定问题?br />
2
2
-
SAT问题有何Ҏ(gu)性?该如何求解?
3
我们从一道例题来认识2
-
SAT问题Qƈ提出对一c?
-
SAT问题通用的解法?br />
4
Poi
0106
Peaceful Commission [和^委员?x)]Q?br /> 某国有n个党z,每个党派在议?x)中恰?个代表?br /> 现在要成立和q_员会(x) Q该?x)满I(x) 每个党派在和q_员会(x)中有且只有一个代表?br /> 如果某两个代表不和,则他们不能都属于委员?x)?br /> 代表的编号从1?nQ编号ؓ(f)2a
-
1
?a的代表属于第a个党z?br />
输入nQ党z数Q,mQ不友好Ҏ(gu)Q及(qing)m对两两不和的代表~号 其中1≤n?/span>
8000
Q?/span>
0
≤m ?/span>
20000
求和q_员会(x)是否能创立。若能,求一U构成方式。?br /> 输入Q 输出:(x)
3
2
1
1
3
4
2
4
5
原题可描qCؓ(f)Q?br /> 有n个组Q第i个组里有两个节点Ai, Ai
'
。需要从每个l中选出一个。而某些点不可以同旉出Q称之ؓ(f)不相容)。Q务是保证选出的n个点都能两两相容?/span>
Q在q里把Ai, Ai
'
的定义稍E放宽一些,它们同时表示属于同一个组的两个节炏V也是_(d)如果我们描述AiQ那么描q这个组的另一个节点就可以用Ai
'
Q?br />
初步构图 如果Ai与Aj不相容,那么如果选择了AiQ必选择Aj‘ ;同样Q如果选择了AjQ就必须选择Ai’ ?br /> Ai Aj
'
Aj Ai‘ ?br /> q样的两条边对称
我们从一个例子来看:(x) 假设4个组Q不和的代表为:(x)1?Q??Q??Q那么构图:(x) 假设Q首先? 3必须选,2不可选?必须选,
4
?不可选?/span>
5
?可以任选一?br />
矛盾的情况ؓ(f)Q?br /> 存在AiQ得Ai既必被选又不可选?br /> 得到法1Q?br /> 枚D每一对尚未确定的Ai, Ai‘ ,任?个,推导出相关的l,若不矛盾Q则可选择Q否则选另1个,同样推导。若矛盾Q问题必定无解?br /> 此算法正性简要说明:(x) ׃Ai,Ai
'
都是未定的,它们不与之前的组相关联,前面的选择不会(x)影响Ai, Ai
'
?br /> 法的时间复杂度在最坏的情况下ؓ(f)O(nm)?br /> 在这个算法中Qƈ没有很好的利用图中边的对U?br />
更一般的_(d)(x) 在每个一个环里,L一个点的选择代表要选择此环里的每一个点。不妨把环收~成一个子节点Q规定这L(fng)环是极大通子图)。新节点的选择表示选择q个节点所对应的环中的每一个节? 对于原图中的每条边Ai
->
AjQ设Ai属于环SiQAj属于环SjQ如果Si≠SjQ则在新图中q边:Si
->
Sj q样构造出一个新的有向无环图?br /> 此图与原囄仗?br />
通过求强q通分量,可以把图转换成新的有向无环图Q在q个基础上,介绍一个新的算法?br /> 新算法中Q如果存在一对Ai, Ai
'
属于同一个环Q则判无解,否则采用拓扑排序,以自底向上的序q行推导Q一定能扑ֈ可行解?/span>
至于q个法的得来及(qing)正确性,在下一D|字中q行详细分析?br /> 回忆构图的过E:(x) 对于两个不相容的点 Ai, AjQ构图方式ؓ(f)QAi
->
Aj
'
,Aj->Ai
'
,前面提到q,q样的两条边对称Q也是_(d)(x) 如果存在Ai
->
AjQ必定存在Aj
'
->Ai
'
?br /> {h(hun)于:(x)Ai
->
Ak,Ak
'
->Ai
'
方便赯Q之后?/span>
->
”代表这样一U传递关p?
猜测1Q图中的环分别对U?br /> 如果存在Ai,AjQAi,Aj属于同一个环(CSi),那么Ai
'
, Aj
'
也必定属于一个环(CSi
'
).
再根据前面的引理Q不难推断出每个环分别对U。?br /> 证明方式与引理相cM 一个稍E复杂点的结?其中U、蓝色部分分别ؓ(f)两组对称的链l构 推广2Q对于Q意一对Si, Si
'
QSi的后代节点与Si
'
的前代节点相互对U。?br /> l而提? 猜测2Q若问题无解Q则必然存在Ai, Ai
'
Q得Ai,Ai
'
属于同一个环。也是Q如果每一对Ai,Ai
'
都不属于同一个环Q问题必定有解。下面给出简略证明:(x)
先提Z个跟法1怼的步骤:(x) 如果选择SiQ那么对于所有Si
->
SjQSj都必被选择。?br /> 而Si
'
必定不可选,q样Si’的所有前代节点也必定不可选(这一q程UC为删除)?/span>
由推q?可以得到Q这L(fng)删除不会(x)D矛盾?br /> 假设选择S3
'
选择S3
'
的后代节? S1
'
删除S3 删除S3的前代节点S1 S1与S1
'
是对U的
每次扑ֈ一个未被确定的SiQ得不存在Si
->
Si
'
选择Si?qing)其后代节点而删除Si’及(qing)Si‘的前代节点。一定可以构造出一l可行解?/span>
因此猜测2成立?br /> 另外Q若每次盲目的去找一个未被确定的SiQ时间复杂度相当高?br /> 以自底向上的序q行选择、删除,q样q可以免厠Z选择Si的后代节点”这一步?br /> 用拓扑排序实现自底向上的序?br /> 一l可能的拓扑序列(自底向上Q?S1
'
,S2,S2
'
,S3
'
,S3,S1
法2的流E:(x)
1
Q构?br />
2
Q求囄极大通子?br />
3
Q把每个子图收羃成单个节点,Ҏ(gu)原图关系构造一个有向无环图
4
Q判断是否有解,无解则输出(退出)
5
Q对新图q行拓扑排序
6
Q自底向上进行选择、删?br />
7
Q输?br /> 结Q?br /> 整个法的时间复杂度大概是O(m)Q解x问题可以说是相当有效了?br /> 在整个算法的构造、证明中反复提到了一个词Q对U。发现、利用了q个囄Ҏ(gu)性质Q我们才能够很好的解决问题?br /> q且Q由2
-
SAT问题模型变换出的cM的题目都可以用上q方法解冟뀂?br /> 全文ȝQ?br /> 充分挖掘囄性质Q能够更好的解决问题?br /> 不仅仅是对于图论Q这U思想可以在很多问题中得到很好的应用?br /> 希望我们能掌握此U解题的思想Q在熟练基础法的同时深入分析、灵z运用、大胆创斎ͼ从而解x多更新的N?br />
]]>军_考研。。?/title> http://m.shnenglu.com/ACflying/archive/2009/05/31/86315.htmlKNIGHT KNIGHT Sun, 31 May 2009 13:44:00 GMT http://m.shnenglu.com/ACflying/archive/2009/05/31/86315.html http://m.shnenglu.com/ACflying/comments/86315.html http://m.shnenglu.com/ACflying/archive/2009/05/31/86315.html#Feedback 0 http://m.shnenglu.com/ACflying/comments/commentRss/86315.html http://m.shnenglu.com/ACflying/services/trackbacks/86315.html 从此一节课不逃。。。。。周六,周日?73.或者看资料。。?br />Bless pip! ]]> 写点头文件之c?/title> http://m.shnenglu.com/ACflying/archive/2009/05/29/86120.htmlKNIGHT KNIGHT Fri, 29 May 2009 14:14:00 GMT http://m.shnenglu.com/ACflying/archive/2009/05/29/86120.html http://m.shnenglu.com/ACflying/comments/86120.html http://m.shnenglu.com/ACflying/archive/2009/05/29/86120.html#Feedback 0 http://m.shnenglu.com/ACflying/comments/commentRss/86120.html http://m.shnenglu.com/ACflying/services/trackbacks/86120.html #define MFW() freopen("MyData.out","w",stdout); #define FW() freopen("Data.out","w",stdout); #define FR() freopen("Data.in","r",stdin); #define FOR(s,i,t) for(i=s;i<=t;i++) #define FUCK puts("Fuck You!"); #define PAUSE system("pause"); #define getmax(x,y) x>y?x:y; #define getmin(x,y) x<y?x:y; #define Abs(x) x>0?x?-x; #define OK puts("OK!"); #define INF 0x7fffffff #define MIO FR()FW() #define IO FR()FW() #define MAXN 1200 #define EPS 1E-8 #include< algorithm > #include< iostream > #include< string > #include< vector > #include< bitset > #include< queue > #include< stack > #include< list > #include< map > #include< set > int main() { IO OK } ]]> [ZZ]后缀数组 http://m.shnenglu.com/ACflying/archive/2009/05/28/86031.htmlKNIGHT KNIGHT Thu, 28 May 2009 11:53:00 GMT http://m.shnenglu.com/ACflying/archive/2009/05/28/86031.html http://m.shnenglu.com/ACflying/comments/86031.html http://m.shnenglu.com/ACflying/archive/2009/05/28/86031.html#Feedback 2 http://m.shnenglu.com/ACflying/comments/commentRss/86031.html http://m.shnenglu.com/ACflying/services/trackbacks/86031.html
在字W串处理当中Q后~?wi)和后缀数组都是非常有力的工P其中后缀?wi)大家了解得比较多,关于后缀数组则很见于国内的资料。其实后~数组是后~?wi)的一个非常精巧的替代品,它比后缀?wi)容易编E实玎ͼ能够实现后缀?wi)的很多功能而时间复杂度也不太逊色Qƈ且,它比后缀?wi)所占用的空间小很多。可以说Q在信息学竞赛中后缀数组比后~?wi)要更?f)实用。因此在本文中笔者想介绍一下后~数组的基本概c(din)构造方法,以及(qing)配合后缀数组的最长公共前~数组的构造方法,最后结合一些例子谈谈后~数组的应用? 基本概念 首先明确一些必要的定义Q? 字符?一个字W集∑是一个徏立了全序关系的集合,也就是说Q∑中的L两个不同的元素α和β都可以比较大,要么<βQ要么?lt;Q也是>βQ。字W集∑中的元素称为字W? 字符?一个字W串S是将n个字W顺ơ排列Ş成的数组QnUCؓ(f)S的长度,表示为len(S)。S的第i个字W表CZؓ(f)S[i]? 子串 字符串S的子串S[i..j]Qi≤jQ表CS串中从i到jq一D,也就是顺ơ排列S[i],S[i+1],...,S[j]形成的字W串? 后缀 后缀是指从某个位|i开始到整个串末束的一个特D子丌Ӏ字W串S的从i开头的后缀表示为Suffix(S,i)Q也是Suffix(S,i)=S[i..len(S)]? 关于字符串的大小比较Q是指通常所说的“字兔R序”比较,也就是对于两个字W串u、vQo(h)i?开始顺ơ比较u[i]和v[i]Q如果相{则令i?Q否则若u[i]<v[i]则认为u<vQu[i]>v[i]则认为u>vQ也是v<uQ,比较l束。如果i>len (u)或者i>len(v)仍未比较出结果,那么若len(u)<len(v)则认为u<vQ若len(u)=len(v)则认为u= vQ若len(u)>len(v)则u>v? 从字W串的大比较的定义来看QS的两个开头位|不同的后缀u和vq行比较的结果不可能是相{,因ؓ(f)u=v的必要条件len(u)=len(v)在这里不可能满? 下面我们U定一个字W集∑和一个字W串SQ设len(S)=nQ且S[n]='$'Q也是说S以一个特D字W?$'l尾Qƈ?$'于∑中的Q何一个字W。除了S[n]之外QS中的其他字符都属于∑。对于约定的字符串SQ从位置i开头的后缀直接写成Suffix(i)Q省d数S? 后缀数组 后缀数组SA是一个一l数l,它保?..n的某个排列SA[1],SA[2],...SA[n]Qƈ且保?Suffix(SA[i])<Suffix(SA[i+1]),1≤i<n。也是S的n个后~从小到大q行排序之后把排好序的后~的开头位|顺ơ放入SA中? 名次数组 名次数组Rank=SA-1Q也是说若SA[i]=jQ则Rank[j]=iQ不隄出Rank[i]保存的是Suffix(i)在所有后~中从到大排列的“名ơ”? 构造方? 如何构造后~数组呢?最直接最单的Ҏ(gu)当然是把S的后~都看作一些普通的字符Ԍ按照一般字W串排序的方法对它们从小到大q行排序? 不难看出Q这U做法是很笨拙的Q因为它没有利用到各个后~之间的有p,所以它的效率不可能很高。即佉K用字W串排序中比较高效的Multi-key Quick SortQ最坏情늚旉复杂度仍然是O(n2)的,不能满我们的需要? 下面介绍倍增法(Doubling Algorithm)Q它正是充分利用了各个后~之间的联p,构造后~数组的最坏时间复杂度成功降至O(nlogn)? 对一个字W串uQ我们定义u的k-前缀 定义k-前缀比较关系<k?k和≤kQ? 设两个字W串u和vQ? u<kv 当且仅当 uk<vk u=kv 当且仅当 uk=vk u≤kv 当且仅当 uk≤vk 直观地看q些加了一个下标k的比较符L(fng)意义是对两个字W串的前k个字W进行字典序比较Q特别的一点就是在作大于和于的比较时如果某个字符串的长度不到k也没有关p,只要能够在k个字W比较结束之前得到第一个字W串大于或者小于第二个字符串就可以了? Ҏ(gu)前缀比较W的性质我们可以得到以下的非帔R要的性质Q? 性质1.1 对k≥nQSuffix(i)<kSuffix(j) {h(hun)?Suffix(i)<Suffix(j)? 性质1.2 Suffix(i)=2kSuffix(j){h(hun)? Suffix(i)=kSuffix(j) ?Suffix(i+k)=kSuffix(j+k)? 性质1.3 Suffix(i)<2kSuffix(j) {h(hun)? Suffix(i)<kS(j) ?(Suffix(i)=kSuffix(j) ?Suffix(i+k)<kSuffix(j+k))? q里有一个问题,当i+k>n或者j+k>n的时候Suffix(i+k)或Suffix(j+k)是无明确定义的表辑ּQ但实际上不需要考虑q个问题Q因为此时Suffix(i)或者Suffix(j)的长度不过kQ也是说它们的k-前缀?$'l尾Q于是k-前缀比较的结果不可能相等Q也是说前k个字W已l能够比出大,后面的表辑ּ自然可以忽略Q这也就看出我们规定S?$'l尾的特D用处了? 定义k-后缀数组 SAk保存1..n的某个排列SAk[1],SAk[2],…SAk[n]使得Suffix(SAk[i]) ≤kSuffix(SAk[i+1]),1≤i<n。也是说对所有的后缀在k-前缀比较关系下从到大排序,q且把排序后的后~的开头位|顺ơ放入数lSAk中? 定义k-名次数组RankkQRankk[i]代表Suffix(i)在k-前缀关系下从到大的“名ơ”,也就?加上满Suffix(j)<kSuffix(i)的j的个数。通过SAk很容易在O(n)的时间内求出Rankk? 假设我们已经求出了SAk和RankkQ那么我们可以很方便地求出SA2k和Rank2kQ因为根据性质1.2?.3Q?k-前缀比较关系可以由常Ck -前缀比较关系l合h{h(hun)地表达,而Rankk数组实际上给Z在常数时间内q行<k?k比较的方法,卻I(x) Suffix(i)<kSuffix(j) 当且仅当 Rankk[i]<Rankk[j] Suffix(i)=kSuffix(j) 当且仅当 Rankk[i]=Rankk[j] 因此Q比较Suffix(i)和Suffix(j)在k-前缀比较关系下的大小可以在常数时间内完成Q于是对所有的后缀在≤k关系下进行排序也和一般的排序没有什么区别了Q它实际上就相当于每个Suffix(i)有一个主关键字Rankk[i]和一个次关键字Rankk[i+k]。如果采用快速排序之cO (nlogn)的排序,那么从SAk和Rankk构造出SA2k的复杂度是O(nlogn)。更聪明的方法是采用基数排序Q复杂度为O(n)? 求出SA2k之后可以在O(n)的时间内Ҏ(gu)SA2k构造出Rank2k。因此,从SAk和Rankk推出SA2k和Rank2k可以在O(n)旉内完成? 下面只有一个问题需要解冻I(x)如何构造出SA1和Rank1。这个问题非常简单:(x)因ؓ(f)<1Q?1和≤1q些q算W实际上是对字W串的第一个字W进行比较,所以只要把每个后缀按照它的W一个字W进行排序就可以求出SA1Q不妨就采用快速排序,复杂度ؓ(f)O(nlogn)? 于是Q可以在O(nlogn)的时间内求出SA1和Rank1? 求出了SA1和Rank1Q我们可以在O(n)的时间内求出SA2和Rank2Q同P我们可以再用O(n)的时间求出SA4和Rank4Q这P我们依次求出Q? SA2和Rank2QSA4和Rank4QSA8和Rank8Q……直到SAm和RankmQ其中m=2k且m≥n。而根据性质1.1QSAm和SA是等L(fng)。这样一共需要进行lognơO(n)的过E,因此 可以在O(nlogn)的时间内计算出后~数组SA和名ơ数lRank? 最长公共前~ 现在一个字W串S的后~数组SA可以在O(nlogn)的时间内计算出来。利用SA我们已经可以做很多事情,比如在O(mlogn)的时间内q行模式匚wQ其中m,n分别为模式串和待匚w串的长度。但是要x充分地发挥后~数组的威力,我们q需要计一个辅助的工具——最长公共前~QLongest Common PrefixQ? 对两个字W串u,v定义函数l(f)cp(u,v)=max{i|u=iv}Q也是从头开始顺ơ比较u和v的对应字W,对应字符持箋相等的最大位|,UCؓ(f)q两个字W串的最长公共前~? Ҏ(gu)整数i,j定义LCP(i,j)=lcp(Suffix(SA[i]),Suffix(SA[j])Q其中i,j均ؓ(f)1至n的整数。LCP(i,j)也就是后~数组中第i个和Wj个后~的最长公共前~的长度? 关于LCP有两个显而易见的性质Q? 性质2.1 LCP(i,j)=LCP(j,i) 性质2.2 LCP(i,i)=len(Suffix(SA[i]))=n-SA[i]+1 q两个性质的用处在于,我们计算LCP(i,j)时只需要考虑i<j的情况,因ؓ(f)i>j时可交换i,jQi=j时可以直接输出结果n-SA[i]+1? 直接Ҏ(gu)定义Q用次比较对应字符的方法来计算LCP(i,j)昄是很低效的,旉复杂度ؓ(f)O(n)Q所以我们必进行适当的预处理以降低每ơ计LCP的复杂度? l过仔细分析Q我们发现LCP函数有一个非常好的性质Q? 设i<jQ则LCP(i,j)=min{LCP(k-1,k)|i+1≤k≤j} QLCP TheoremQ? 要证明LCP TheoremQ首先证明LCP Lemma: 对Q?≤i<j<k≤nQLCP(i,k)=min{LCP(i,j),LCP(j,k)} 证明Q设p=min{LCP(i,j),LCP(j,k)}Q则有LCP(i,j)≥p,LCP(j,k)≥p? 设Suffix(SA[i])=u,Suffix(SA[j])=v,Suffix(SA[k])=w? 由u=LCP(i,j)v得u=pvQ同理v=pw? 于是Suffix(SA[i])=pSuffix(SA[k])Q即LCP(i,k)≥p?(1) 又设LCP(i,k)=q>pQ则 u[1]=w[1],u[2]=w[2],...u[q]=w[q]? 而min{LCP(i,j),LCP(j,k)}=p说明u[p+1]≠v[p+1]或v[p+1]≠w[q+1]Q? 设u[p+1]=x,v[p+1]=y,w[p+1]=zQ显然有x≤y≤zQ又由p<q得p+1≤qQ应该有x=zQ也是x=y=zQ这与u[p+1]≠v[p+1]或v[p+1]≠w[q+1]矛盾? 于是Qq>p不成立,即LCP(i,k)≤p?(2) l合(1),(2)?LCP(i,k)=p=min{LCP(i,j),LCP(j,k)}QLCP Lemma得证? 于是LCP Theorem可以证明如下Q? 当j-i=1和j-i=2Ӟ昄成立? 设j-i=m时LCP Theorem成立Q当j-i=m+1Ӟ 由LCP Lemma知LCP(i,j)=min{LCP(i,i+1),LCP(i+1,j)}Q? 因j-(i+1)≤mQLCP(i+1,j)=min{LCP(k-1,k)|i+2≤k≤j}Q故当j-i=m+1Ӟ仍有 LCP(i,j)=min{LCP(i,i+1),min{LCP(k-1,k)|i+2≤k≤j}}=min{LCP(k-1,k}|i+1≤k≤j) Ҏ(gu)数学归纳法,LCP Theorem成立? Ҏ(gu)LCP Theorem得出必然的一个推论:(x) LCP Corollary 对i≤j<kQLCP(j,k)≥LCP(i,k)? 定义一l数lheightQo(h)height[i]=LCP(i-1,i)Q?<i≤nQƈ设height[1]=0? 由LCP TheoremQLCP(i,j)=min{height[k]|i+1≤k≤j}Q也是_(d)计算LCP(i,j){同于询问一l数lheight中下标在i+1到j范围内的所有元素的最倹{如果height数组是固定的Q这是非常l典的RMQQRange Minimum QueryQ问题? RMQ问题可以用线D|(wi)或静态排序树(wi)在O(nlogn)旉内进行预处理Q之后每ơ询问花Ҏ(gu)间O(logn)Q更好的Ҏ(gu)是RMQ标准法Q可以在O(n)旉内进行预处理Q每ơ询问可以在常数旉内完成? 对于一个固定的字符串SQ其height数组昄是固定的Q只要我们能高效地求出height数组Q那么运用RMQҎ(gu)q行预处理之后,每次计算LCP(i,j)的时间复杂度是常数U了。于是只有一个问题——如何尽量高效地出height数组? Ҏ(gu)计算后缀数组的经验,我们不应该把n个后~看作互不相关的普通字W串Q而应该尽量利用它们之间的联系Q下面证明一个非常有用的性质Q? Z描述方便Q设h[i]=height[Rank[i]]Q即height[i]=h[SA[i]]。h数组满一个性质Q? 性质3 对于i>1且Rank[i]>1Q一定有h[i]≥h[i-1]-1? Z证明性质3Q我们有必要明确两个事实Q? 设i<n,j<nQSuffix(i)和Suffix(j)满lcp(Suffix(i),Suffix(j)>1Q则成立以下两点Q? Fact 1 Suffix(i)<Suffix(j) {h(hun)?Suffix(i+1)<Suffix(j+1)? Fact 2 一定有lcp(Suffix(i+1),Suffix(j+1))=lcp(Suffix(i),Suffix(j))-1? 看v来很奇Q但其实很自Ӟ(x)lcp(Suffix(i),Suffix(j))>1说明Suffix(i)和Suffix(j)的第一个字W是相同的,讑֮为α,则Suffix(i)相当于α后q接Suffix(i+1)QSuffix(j)相当于α后q接Suffix(j+1)。比较Suffix (i)和Suffix(j)ӞW一个字Wα是一定相{的Q于是后面就{h(hun)于比较Suffix(i)和Suffix(j)Q因此Fact 1成立。Fact 2可类D明? 于是可以证明性质3Q? 当h[i-1]?Ӟl论昄成立Q因h[i]?≥h[i-1]-1? 当h[i-1]>1Ӟ也即height[Rank[i-1]]>1Q可见Rank[i-1]>1Q因height[1]=0? 令j=i-1,k=SA[Rank[j]-1]。显然有Suffix(k)<Suffix(j)? Ҏ(gu)h[i-1]=lcp(Suffix(k),Suffix(j))>1和Suffix(k)<Suffix(j)Q? 由Fact 2知lcp(Suffix(k+1),Suffix(i))=h[i-1]-1? 由Fact 1知Rank[k+1]<Rank[i]Q也是Rank[k+1]≤Rank[i]-1? 于是Ҏ(gu)LCP CorollaryQ有 LCP(Rank[i]-1,Rank[i])≥LCP(Rank[k+1],Rank[i]) =lcp(Suffix(k+1),Suffix(i)) =h[i-1]-1 ׃h[i]=height[Rank[i]]=LCP(Rank[i]-1,Rank[i])Q最l得?h[i]≥h[i-1]-1? Ҏ(gu)性质3Q可以o(h)i?循环到n按照如下Ҏ(gu)依次出h[i]Q? 若Rank[i]=1Q则h[i]=0。字W比较次Cؓ(f)0? 若i=1或者h[i-1]?Q则直接Suffix(i)和Suffix(Rank[i]-1)从第一个字W开始依ơ比较直到有字符不相同,由此计算出h[i]。字W比较次Cؓ(f)h[i]+1Q不过h[i]-h[i-1]+2? 否则Q说明i>1QRank[i]>1Qh[i-1]>1Q根据性质3QSuffix(i)和Suffix(Rank[i]-1)臛_有前h[i-1]-1个字W是相同的,于是字符比较可以从h[i-1]开始,直到某个字符不相同,由此计算出h[i]。字W比较次Cؓ(f)h[i]-h[i- 1]+2? 设SA[1]=pQ那么不隄出ȝ字符比较ơ数不超q? 也就是说Q整个算法的复杂度ؓ(f)O(n)? 求出了h数组Q根据关pdheight[i]=h[SA[i]]可以在O(n)旉内求出height数组Q于? 可以在O(n)旉内求出height数组? l合RMQҎ(gu)Q在O(n)旉和空间进行预处理之后p做到在常数时间内计算出对L(i,j)计算出LCP(i,j)? 因ؓ(f)lcp(Suffix(i),Suffix(j))=LCP(Rank[i],Rank[j])Q所以我们也可以在常数旉内求出S的Q何两个后~之间的最长公共前~。这正是后缀数组能强有力地处理很多字W串问题的重要原因之一?br />后缀数组的应?br />下面l合两个例子谈谈如何q用后缀数组.
例一 多模式串的模式匹配问?br />l定一个固定待匚w串S,长度为n,然后每次输入一个模式串P,长度为m,要求q回P在S中的一个匹配或者返回匹配失?所谓匹配指某个位置i满1≤i≤n-m+1使得S[i..(i+m-1)]=P,也即Suffix(i)=mP. 我们知道,如果只有一个模式串,最好的法是KMP法,旉复杂度ؓ(f)O(n+m),但是如果有多个模式串,我们p考虑做适当的预处理使得Ҏ(gu)个模式串q行匚w所q旉一?最单的预处理莫q于建立S的后~数组(先在S的后面添?$'),然后每次L匚w转化为用二分查找法在SA中找到和P的公共前~最长的一个后~,判断q个最长的公共前缀是否{于m.q样,每次比较P和一个后~的复杂度为O(m),因ؓ(f)最坏情况下可能比较了m个字W?二分查找需要调用比较的ơ数为O(logn),因此d杂度为O(mlogn),于是每次匚w的复杂度从O(n+m)变ؓ(f)O(mlogn),可以说改q了不少.可是q样仍然不能令我们满?前面提到LCP可以增加后缀数组的威? 我们来试试用在这个问题上. 我们分析原始的二分查扄?大体有以下几? Step 1 令left=1,right=n,max_match=0. Step 2 令mid=(left+right)/2(q里"/"表示取整除法). Step 3 次比较Suffix(SA[mid])和P的对应字W?扑ֈ两者的最长公?br />前缀r,q判断出它们的大关p?若r>max_match则o(h)max_match=r,ans=mid. Step 4 若Suffix(SA[mid])P则o(h) right=mid-1,若Suffix(SA[mid])=P则{至Step 6. Step 5 若left Step 6 若max_match=m则输出ans,否则输出"无匹?. 注意力很快集中在Step 3,如果能够避免每次都从头开始比较Suffix(SA[mid])和P的对应字W?也许复杂度就可以q一步降?cM于前面求height数组,我们考虑利用以前求得的最长公共前~作ؓ(f)比较?基础",避免冗余的字W比? 在比较Suffix(SA[mid])和P之前,我们先用常数旉计算LCP(mid,ans),然后比较LCP(mid,ans)和max_match:情况一:LCP(mid,ans)k+1,T[i-r'..i-1]和T[i+1..i+r']也不可能关于T[i]对称?所以r最大只能到k.我们把r递增的过E称为向两边扩展,扩展一ơ就可以把以T[i]Z心的奇回文子串的长度?.最后r扩展到的最大值决定了以T[i]Z心的奇回文子串中的最长者的长度(?r+1).设len(T)=m,如果用依ơ比较对应字W的Ҏ(gu)来求向两Ҏ(gu)展的最大?则最多可能比较m-1个字W?׃要枚举每个位|作Z心向两边扩展,所以最坏情况下ȝ复杂度可以达到O(m2),不很理想. 下面优化法的核心部?br />——以一个位|ؓ(f)中心求向两边扩展的最大? 在T串的末尾d一个特D字W?#',规定它不{于T的Q何一个字W?然后把T串颠?接在'#'?在T'串后再添加特D字W?$',规定它小于前面的M一个字W?拼接后Ş成的串称为S?不难看出T串中M一个字W都可在T'中对U地扑ֈ一个相同的字符.如果都用S里的字符来表C?S[1..m]是T?S[m+2..2m+1]是T'?则每个S[i](1≤i≤m)关于'#'对称的字W是S[2m-i+2].q样原先T串里面的一个子串S[i..j](1≤i≤j≤m)关于'#'也可以对U地扑ֈ一个反相{的子串S[2m-j+2..2m-i+2]. 现在我们定下T串的某个位置S[i]Z?假设向两Ҏ(gu)展到了i-r和i+r,那么S[i-r..i-1]和S[i+1..i+r]是反相{的,S[i]可以在T'中找到对U的字符S[2m-i+2],设i'=2m-i+2,则S[i-r..i-1]也可以在T'中找到对U的子串S[i'+1..i'+r], banana#ananab$ TT' ii'=2m-i+2 那么S[i+1..i+r]和S[i'+1..i'+r]同时与S[i-r..i-1]反射相等,也就是说,S[i+1..i+r]=S[i'+1..i'+r].又因为S[i]=S[i'],故S[i..i+r]=S[i'..i'+r].也就是说,Suffix(i)=r+1Suffix(i').现在要求r量?也就是求max{r|Suffix(i)=r+1Suffix(i')},不难看出,q里r=LCP(i,i')-1.上面的推理还存在一个问?x出的LCP(i,i')-1q只能看作r的一个上?q不能当成r的最大?因ؓ(f)q需要证明给出Suffix(i)和Suffix(i')的最长公共前~,一定可以反q来在T串中扑ֈ相应的以iZ心的回文?q个证明与前面的推理cM,只是需要注意一?q里利用C'#'q个Ҏ(gu)字符避免了潜在的LCP(i,i')过实际的r最大值的危险.q个证明留给读者自行完?M,我们已经定求以T[i]Z心向两边扩展的最大值等价于求LCP(i,i'),Ҏ(gu)前面后缀数组和LCP的相兛_容这一步操作可以在常数旉内完?只要我们预先pO(nlogn)的复杂度计算后缀数组,height数组和进行预处理.其中n=len(S)=2m+2. 现在每次求以一个位|T[i]Z心的回文子串中的最长者的长度可以在常数时间内完成,我们枚Di?到m,依次求出所有的q些最长?记录其中最大的一个的长度,是所要求的最长奇回文子串的长?׃Ҏ(gu)个中心花Ҏ(gu)间ؓ(f)常数,所以ȝ复杂度ؓ(f)O(m).因此整个法的复杂度是O(nlogn+m)=O(2mlog(2m)+m)=O(mlogm),是非怼U的算?比之前的qxU算法大为改q? 后缀数组与后~?wi)的比?br />通过上面的两个例子相信读者已l对后缀数组的强大功能有所了解,另一U数据结构——后~?也可以用在这些问题中,那么后缀数组和后~?wi)有什么区别和联系?我们来比较一? 首先,后缀数组比较Ҏ(gu)理解,也易于编E实?而且不像后缀?wi)那样需要涉?qing)到指针操?所以调试v来比较方?W二,后缀数组占用的空间比后缀?wi)要?刚才分析中我们ƈ没有提到I间复杂度的问题,q里单说一?后缀数组SA和名词数lRank都只需要n个整数的I间,而在由Rankk计算出SA2k的过E中需要用两个一l数l来辅助完成,各占n个整数的I间,滚动地进行操?整个法只需要这四个一l数l和常数个辅助变?因此ȝI间占用?n个整?而后~?wi)通常?n个以上节?通常每个节点要两个整?即采用一些技?臛_q是要保存一个整?,每个节点要有两个指针(假设采用儿子-兄弟表示Ҏ(gu)),因此d的空间占用至是4n个指针和2n个整?臛_是n个整?.如果采用其他Ҏ(gu)表示?wi)状l构,需要的I间更大.可以看出后缀数组的空间需求比后缀?wi)? 最后比较它们的复杂? 首先按照字符L|∑|把字W集∑分ZU类? 若|∑|是一个常?则称∑ؓ(f)Constant Alphabet, 若|∑|的大是关于S的长度n的多式函数,则称∑ؓ(f)Integer Alphabet, 若|∑|没有大小上的限制,则称∑ؓ(f)General Alphabet. 昄Constant Alphbet属于Integer Alphabet的一U?而Integer Alphabet是General Alphabet的一U?构造后~数组的复杂度与字W集无关,因ؓ(f)它是直接针对General Alphabet的算?对于普通方法构造后~?如果用儿?兄弟方式表达?wi)状l构,旉复杂度达到O(n*|∑|),昄对于Integer Alphabet ?General Alphabet都很低效,对|∑|较大的Constant Alphabet也不适用.解决的方法是用^衡二叉树(wi)来保存指向儿子的指针,q样复杂度变为O(n*log|∑|).可见后缀?wi)在某些情况下相对后~数组有速度上的优势,但是q不明显.对于|∑|很小的字W串,后缀?wi)相比后~数组的速度优势q是比较可观?其是对于很常见?-1? 后缀数组实际上可以看作后~?wi)的所有叶l点按照从左到右的次序排列放入数l中形成?所以后~数组的用途不可能出后缀?wi)的范?甚至可以?如果不配合LCP,后缀数组的应用范围是很狭H的.但是LCP函数配合下的后缀数组非常强?可以完成大多数后~?wi)所能完成的d,因ؓ(f)LCP函数实际上给ZL两个叶子l点的最q公q?q方面的内容大家可以自行?br />I?后缀?wi)和后缀数组都是字符串处理中非常优秀的数据结?不能说一个肯定优于另一?对于不同场合,不同条g的问?我们应该灉|应用,_ֿ选择地选择其中较ؓ(f)适合的一?法和数据结构都是死?而运用它们的?才是真正的主?对经典的法和数据结构熟l掌握ƈ适当地运用以发挥它们最大的力量,q才是信息学研究和竞赛中最大的智慧,也是信息学竞赛的力 所? ]]> 刚做的TC http://m.shnenglu.com/ACflying/archive/2009/05/28/85956.htmlKNIGHT KNIGHT Wed, 27 May 2009 16:25:00 GMT http://m.shnenglu.com/ACflying/archive/2009/05/28/85956.html http://m.shnenglu.com/ACflying/comments/85956.html http://m.shnenglu.com/ACflying/archive/2009/05/28/85956.html#Feedback 1 http://m.shnenglu.com/ACflying/comments/commentRss/85956.html http://m.shnenglu.com/ACflying/services/trackbacks/85956.html 延时15分钟本来本子没有电(sh)。。。。。现在还没比完就?000分的本子搞不住了。。写下日志就差不多over?br />有点困。。。。?000分题目都没心情看?250的题晕了 费了很多时间。。。。?00的倒是很快推出来了 可惜 想了一U情况从新提交了一ơ。。。。。晕 睡觉了。。。。rating也没性情看了 正式的第一ơTC差不多能够绿了吧。。。。应该能够。。?br />睡觉?img src ="http://m.shnenglu.com/ACflying/aggbug/85956.html" width = "1" height = "1" /> ]]> 省赛告一D落 http://m.shnenglu.com/ACflying/archive/2009/05/26/85807.htmlKNIGHT KNIGHT Tue, 26 May 2009 08:33:00 GMT http://m.shnenglu.com/ACflying/archive/2009/05/26/85807.html http://m.shnenglu.com/ACflying/comments/85807.html http://m.shnenglu.com/ACflying/archive/2009/05/26/85807.html#Feedback 0 http://m.shnenglu.com/ACflying/comments/commentRss/85807.html http://m.shnenglu.com/ACflying/services/trackbacks/85807.html 备战四省赛。。。一切都没有变。。?br />如xiaoz所_(d)(x)AC才是王道?br />just do it。no matter what happen。Go。! ]]> 后天省赛?/title> http://m.shnenglu.com/ACflying/archive/2009/05/22/85470.htmlKNIGHT KNIGHT Fri, 22 May 2009 14:00:00 GMT http://m.shnenglu.com/ACflying/archive/2009/05/22/85470.html http://m.shnenglu.com/ACflying/comments/85470.html http://m.shnenglu.com/ACflying/archive/2009/05/22/85470.html#Feedback 1 http://m.shnenglu.com/ACflying/comments/commentRss/85470.html http://m.shnenglu.com/ACflying/services/trackbacks/85470.html ׃昨天睡得晚了些今天早?点就h打扫寝室Q说什么防止猪感做寝室检查,中午惛_宿舍睡一觉也没睡Q就在实验室WSQ?br />晚上的时候从头翻QQ日志Q感觉有Ҏ(gu)伤的气氛q了一删一,l果194删完。。。从此在q个Blog写东西省赛做完之后尽快达?00Q封P之后完美的做TC?br /> 后天省赛了,或者说要被工大的众牛虐了Q在q里Bless Every Hrbeu‘s Acmers取得好成l! ]]>
þ |
þ99Ʒ |
þþþӰԺŮ |
ƷþþþAV |
Ʒ18þþþþvr |
Ҳȥþۺ |
ɫۺϾþۺۿ |
91Ʒþþþþ
|
ݺɫþ |
˾Ʒþ |
AŮAVۺϾþþ |
ۺպþóAV |
99ŷþþþƷѿ |
þѸƵ |
þþþþþƵ |
˾Ʒþ |
þƷһ |
aѹۿþav |
ھƷþþþ |
ij˾þþþӰԺѹۿ
|
˾ƷþѶ |
þøƬ |
þݺҹҹ2O2O |
þùҹƵ |
þɫۺһ |
þþƷ鶹 |
þ91Ʒ91 |
ҹþþþƷӰԺ |
ɫۺϾþ |
Ʒþþ |
ɫۺϾþĻ |
ƷѾþ |
Ʒþþþþù˽ |
ۺһ˾þþƷ |
þþһ |
ŷ˾þô߽ۺ69 |
AëƬþ |
þþŷղAV |
ԭۺϾþ |
AëƬþ |
avþþƷ |