??xml version="1.0" encoding="utf-8" standalone="yes"?>久久综合噜噜激激的五月天,久久伊人精品一区二区三区,伊人久久综合成人网http://www.shnenglu.com/MatoNo1/archive/2013/08/31/202905.htmlMato_No1Mato_No1Sat, 31 Aug 2013 15:39:00 GMThttp://www.shnenglu.com/MatoNo1/archive/2013/08/31/202905.htmlhttp://www.shnenglu.com/MatoNo1/comments/202905.htmlhttp://www.shnenglu.com/MatoNo1/archive/2013/08/31/202905.html#Feedback1http://www.shnenglu.com/MatoNo1/comments/commentRss/202905.htmlhttp://www.shnenglu.com/MatoNo1/services/trackbacks/202905.html阅读全文

Mato_No1 2013-08-31 23:39 发表评论
]]>
【AHOI2013复仇】二lDP优化的几道题ȝhttp://www.shnenglu.com/MatoNo1/archive/2013/03/03/198185.htmlMato_No1Mato_No1Sun, 03 Mar 2013 07:25:00 GMThttp://www.shnenglu.com/MatoNo1/archive/2013/03/03/198185.htmlhttp://www.shnenglu.com/MatoNo1/comments/198185.htmlhttp://www.shnenglu.com/MatoNo1/archive/2013/03/03/198185.html#Feedback0http://www.shnenglu.com/MatoNo1/comments/commentRss/198185.htmlhttp://www.shnenglu.com/MatoNo1/services/trackbacks/198185.html??a title="BZOJ1713" >BZOJ1713
F[i][j]=max{F[i1][j1] - (sA[i-1]-sA[i1])2 - (sB[j-1]-sB[j1])2} + A[i]*B[j], 0<=i1<i, 0<=j1<j
对这个式子进行化Q?br />F[i][j]=max{F[i1][j1] - sA[i1]2 + 2*sA[i-1]*sA[i1] - sB[j1]2 + 2*sB[j-1]*sB[j1]}+A[i]*B[j]-sA[i-1]2-sB[j-1]2
对于一l的情况Q很Ҏ处理——中间是一条直U,然而这是二l的Q对于这U?D/2D的DP方程Q要优化到O(N2)U别Q需要两步?br />注意到决{式中除了F[i1][j1]外,其它部分都要么只与i1有关Q要么只与j1有关。因此,可以把阶Di的各个状态作Z个整体,在之前得出的各个F[i][j]中,对于相同的jQ找到对于目前的iQ最优的那个决策——注意Q对于相同的j1Q里面所有与j1有关的东襉K可以先不考虑了,只考虑(F[i1][j1] - sA[i1]2 + 2*sA[i-1]*sA[i1])对于目前i的最优决{。这一步可以在q些直线形成的上凸壳中找刎ͼ且满_{单调性,可以用一个栈处理Q斜率优化)。然后,这些最优决{以j变量再组成一些直U,用栈l护它们的上凸壳Q对于每个jQ找到最优值即可?br />注意事项Q在栈中删除直线的时候,如果之前的最优决{是q个被删掉的直线Q则要将最优决{先|ؓ不存在,然后再插入新直线后设为新直线。另外,要特别注意^行的情况?br />
?】LCIS
l典问题Q利用上面的分步优化思想Q很Ҏ用线D|得到一个O(N2logN)的做法?br />
??a title="[SCOI2010]股票交易 " >[SCOI2010]股票交易
F[i][j]=max{F[i-1][j], max{F[i-W-1][j-a]-A*a, F[i-W-1][j+b]+b*B}}, j<=maxP, 1<=a<=maxA, 1<=b<=maxB
注意对于相同的jQ计方法是一LQ且是一条直U(׃有范围所以其实是U段Q?br />所以,计算阶段iӞ可以?i-W-1)阶段所有的决策当成U段插入Q这些线D늚斜率都相{,因此比较好维护,只需要判断边界即可?br />
注意QNOI2011的show虽然也符合对于相同的j计算Ҏ一P但它׃能优化,因ؓ它的决策是不q箋且无规律的,没有M几何性质。因此,它只能用O(N3)的算法计出所有状态?br />

Mato_No1 2013-03-03 15:25 发表评论
]]>
【AHOI2013复仇】动态凸?/title><link>http://www.shnenglu.com/MatoNo1/archive/2013/02/28/198024.html</link><dc:creator>Mato_No1</dc:creator><author>Mato_No1</author><pubDate>Thu, 28 Feb 2013 10:29:00 GMT</pubDate><guid>http://www.shnenglu.com/MatoNo1/archive/2013/02/28/198024.html</guid><wfw:comment>http://www.shnenglu.com/MatoNo1/comments/198024.html</wfw:comment><comments>http://www.shnenglu.com/MatoNo1/archive/2013/02/28/198024.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.shnenglu.com/MatoNo1/comments/commentRss/198024.html</wfw:commentRss><trackback:ping>http://www.shnenglu.com/MatoNo1/services/trackbacks/198024.html</trackback:ping><description><![CDATA[     摘要: 原题地址写了几天l于写出来了……Q显Ӟ我太׃Q请各位犇不要鄙视Q在有加点的情况下,动态地l护凸包Q有以下两种ҎQ?lt;1>l护上、下凸壳Q本沙茶采用的方法)Q凸包可以拆成上、下凸壳Q对它们分别l护。两个凸壛_按照下面定义?lt;关系Q即先x增、再y增)排序Q注意,两个凸壳的两端是相同的,均ؓ整个凸包的最点与最大点Q除两端外,它们没有公共定点。以上凸壳ؓ?..  <a href='http://www.shnenglu.com/MatoNo1/archive/2013/02/28/198024.html'>阅读全文</a><img src ="http://www.shnenglu.com/MatoNo1/aggbug/198024.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.shnenglu.com/MatoNo1/" target="_blank">Mato_No1</a> 2013-02-28 18:29 <a href="http://www.shnenglu.com/MatoNo1/archive/2013/02/28/198024.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>【AHOI2013复仇】向JZPKIL认输?/title><link>http://www.shnenglu.com/MatoNo1/archive/2013/02/06/197761.html</link><dc:creator>Mato_No1</dc:creator><author>Mato_No1</author><pubDate>Wed, 06 Feb 2013 15:26:00 GMT</pubDate><guid>http://www.shnenglu.com/MatoNo1/archive/2013/02/06/197761.html</guid><wfw:comment>http://www.shnenglu.com/MatoNo1/comments/197761.html</wfw:comment><comments>http://www.shnenglu.com/MatoNo1/archive/2013/02/06/197761.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.shnenglu.com/MatoNo1/comments/commentRss/197761.html</wfw:commentRss><trackback:ping>http://www.shnenglu.com/MatoNo1/services/trackbacks/197761.html</trackback:ping><description><![CDATA[RTQ?br />今天又优化了一下JZPKILQ用上了各种无ȝ手段Q仍然无法干掉后两个点,q且BZOJ上的L?0s也无法实玎ͼ后两个点一个就?0sQ,<br />看来Zl合数的做法׃要枚丑֛敎ͼ实不行……<br />Q注Q后两个Ҏ人工构造的猥琐数据Q所有的N都是若干个小质数之积Q因C数都上千Q有的甚至上?#8230;…Q?br /><br />认输?#8230;…<br />Orz @sevenk<img src ="http://www.shnenglu.com/MatoNo1/aggbug/197761.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.shnenglu.com/MatoNo1/" target="_blank">Mato_No1</a> 2013-02-06 23:26 <a href="http://www.shnenglu.com/MatoNo1/archive/2013/02/06/197761.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>【AHOI2013复仇】s-tWK短简单\问题http://www.shnenglu.com/MatoNo1/archive/2012/09/23/191705.htmlMato_No1Mato_No1Sun, 23 Sep 2012 06:28:00 GMThttp://www.shnenglu.com/MatoNo1/archive/2012/09/23/191705.htmlhttp://www.shnenglu.com/MatoNo1/comments/191705.htmlhttp://www.shnenglu.com/MatoNo1/archive/2012/09/23/191705.html#Feedback0http://www.shnenglu.com/MatoNo1/comments/commentRss/191705.htmlhttp://www.shnenglu.com/MatoNo1/services/trackbacks/191705.html[SCOI2007 kshort]
求图的s-tWK短简单\问题Q若有长度相同的Q字典序的优先?br />
首先Q由于是单\Q所?a title="A*" href="http://www.shnenglu.com/MatoNo1/archive/2011/05/01/145456.html">A*是不能做的,因ؓ有可能有两条s-iQi为某个中间点Q\P1和P2QP1比P2短,但由于P1到达的顶点与P2不同Q导致最l沿P1到达t的\径长度长于沿P2到达t的(甚至有可能沿P1ҎC了tQ。然后,如果直接用DFSQ由于要求的是第K优解Q而不是最优解Q所以不能用最优性剪枝(包括分支限界Q,因此专门为最优性剪枝服务的“改变搜烦序”技巧也不能使用了,因此Q能够用的只有可行性剪枝,而本题的数据范围使得q种法必然TLE?br />
正解是一U由q代加深思想扩展得到?#8220;q代变优”DFS。设|一个\径长度上限ZQ搜索s到t的所有简单\Q在搜烦q程中,遇到长度大于Z的\径就停止Q剪枝)Q然后,若得到\径不K条,则增加Z的|重新开始搜索,直到得到的\径L大于{于K条ؓ止。这里可以进行启发式的优化,设g[i]为点i到t的最短\长度Q则搜烦q程中,假设目前搜到点iQ则Q目前\径长?g[i]Q是Ҏ条\径最短长度的乐观估计Q如果这个Dq了ZQ就可以剪枝Q但在剪枝之前要Cq个过了Z的启发|取其中最的作ؓ下一ơP代的Z倹{那么对于字典序肿么办?可以在搜索过E中Q强制先搜编号小的结点,q样得到的s-t路径必然是字典序递增的。另外只要求出第K条\径,搜烦可以终止,因ؓҎ证明Q题目要求的WK短的路径一定已l求出来了(只不q不一定是最后一条而已Q,扑ֈ卛_。此外,在搜索过E中不要忘了可行性剪枝,是如果沿目前搜到的路径已经C了t了,剪枝?br />
“q代变优”DFSQ就是设|一个解的评价值的上限Q最|或下限(最大|Q在搜烦q程中,如果实际评h|或者启发|如果可以加启发式优化的话Q越q这个限Ӟ则剪枝。在一ơ搜索后Q如果没有得到符合要求的解,将该限制?span style="color: red">设ؓ本次搜烦q程中越?#8220;?#8221;得最q的那个?/strong>Q重新开始搜索,直到扑ֈ所需要的解或?span style="color: red">发现无解Q如果一ơ搜索中没有发生界Q却仍然没有扑ֈ解)为止。其应用主要体现在两个方面:Q?Q搜索树q深甚至无限深,但所需求的那个解却不深的情况;Q?Q求WK优解的情c?br />
代码Q?
#include <iostream>
#include 
<stdio.h>
#include 
<stdlib.h>
#include 
<string.h>
#include 
<algorithm>
using namespace std;
#define re(i, n) for (int i=0; i<n; i++)
#define re1(i, n) for (int i=1; i<=n; i++)
#define re2(i, l, r) for (int i=l; i<r; i++)
#define re3(i, l, r) for (int i=l; i<=r; i++)
#define rre(i, n) for (int i=n-1; i>=0; i--)
#define rre1(i, n) for (int i=n; i>0; i--)
#define rre2(i, r, l) for (int i=r-1; i>=l; i--)
#define rre3(i, r, l) for (int i=r; i>=l; i--)
const int MAXN = 51, MAXK = 201, MAXM = 3000, INF = ~0U >> 2;
struct edge {
    
int a, b, w, pre, next;
} E[MAXM 
+ MAXN], E0[MAXM + MAXN];
struct edge0 {
    
int a, b, w;
    
bool operator< (edge0 e0) const {return b < e0.b;}
} _E[MAXM];
int n, m, s, t, K, dist[MAXN], Q[MAXN + 1];
int Z, Z0, vst0[MAXN], _FL, len0, X00[MAXN], No, len[MAXK], X0[MAXK][MAXN], sum0[MAXK], reslen, res[MAXN];
bool vst[MAXN], res_ex = 0;
void init_d()
{
    re(i, n) E[i].pre 
= E[i].next = E0[i].pre = E0[i].next = i; m = n;
}
void add_edge(int a, int b, int w)
{
    E[m].a 
= a; E[m].b = b; E[m].w = w; E[m].pre = E[a].pre; E[m].next = a; E[a].pre = m; E[E[m].pre].next = m;
    E0[m].a 
= b; E0[m].b = a; E0[m].w = w; E0[m].pre = E0[b].pre; E0[m].next = b; E0[b].pre = m; E0[E0[m].pre].next = m++;
}
void init()
{
    
int m0; scanf("%d%d%d%d%d"&n, &m0, &K, &s, &t); init_d(); s--; t--;
    re(i, m0) {scanf(
"%d%d%d"&_E[i].a, &_E[i].b, &_E[i].w); _E[i].a--; _E[i].b--;}
    sort(_E, _E 
+ m0);
    re(i, m0) add_edge(_E[i].a, _E[i].b, _E[i].w);
}
void prepare()
{
    re(i, n) {vst[i] 
= 0; dist[i] = INF;} vst[t] = 1; dist[t] = 0; Q[0= t;
    
int x, y, d0, d1;
    
for (int front=0, rear=0!(!front && rear==|| front==rear+1); front==? front=0 : front++) {
        x 
= Q[front]; d0 = dist[x];
        
for (int p=E0[x].next; p != x; p=E0[p].next) {
            y 
= E0[p].b; d1 = d0 + E0[p].w;
            
if (d1 < dist[y]) {
                dist[y] 
= d1;
                
if (!vst[y]) {vst[y] = 1; Q[rear==? rear=0 : ++rear] = y;}
            }
        }
        vst[x] 
= 0;
    }
}
void dfs(int x, int sum)
{
    
if (x == t) {
        
if (sum <= Z) {sum0[No] = sum; len[No] = len0; re(i, len0) X0[No][i] = X00[i]; No++if (No == K) res_ex = 1;}
        
else if (sum < Z0) Z0 = sum;
        
return;
    } 
else {
        
int h0 = sum + dist[x];
        
if (h0 > Z) {if (h0 < Z0) Z0 = h0; return;}
        vst0[x] 
= ++_FL; Q[0= x; int _x, _y;
        
for (int front=0, rear=0; front<=rear; front++) {
            _x 
= Q[front];
            
for (int p=E[_x].next; p != _x; p=E[p].next) {
                _y 
= E[p].b;
                
if (!vst[_y] && vst0[_y] != _FL) {vst0[_y] = _FL; Q[++rear] = _y;}
            }
        }
        
if (vst0[t] != _FL) return;
        
for (int p=E[x].next; p != x; p=E[p].next) {
            _y 
= E[p].b;
            
if (!vst[_y]) {vst[_y] = 1; X00[len0++= _y; dfs(_y, sum + E[p].w); if (res_ex) returnelse {len0--; vst[_y] = 0;}}
        }
    }
}
void solve()
{
    Z 
= dist[s]; int No0 = 0; _FL = 0;
    
while (1) {
        Z0 
= INF; No = 0; re(i, n) {vst[i] = 0; vst0[i] = 0;}
        vst[s] 
= 1; len0 = 1; X00[0= s; dfs(s, 0);
        
if (res_ex) {
            No0 
= K - No0;
            re(i, K) 
if (sum0[i] == Z) {No0--if (!No0) {reslen = len[i]; re(j, len[i]) res[j] = X0[i][j];}}
            
break;
        } 
else if (Z0 == INF) breakelse {No0 = No; Z = Z0;}
    }
}
void pri()
{
    
if (res_ex) {
        printf(
"%d", res[0+ 1);
        re2(i, 
1, reslen) printf("-%d", res[i] + 1);
        puts(
"");
    } 
else puts("No");
}
int main()
{
    init();
    prepare();
    solve();
    pri();
    
return 0;
}




Mato_No1 2012-09-23 14:28 发表评论
]]>
【AHOI2013复仇】两道LIS模型题ȝhttp://www.shnenglu.com/MatoNo1/archive/2012/09/08/189969.htmlMato_No1Mato_No1Sat, 08 Sep 2012 12:40:00 GMThttp://www.shnenglu.com/MatoNo1/archive/2012/09/08/189969.htmlhttp://www.shnenglu.com/MatoNo1/comments/189969.htmlhttp://www.shnenglu.com/MatoNo1/archive/2012/09/08/189969.html#Feedback1http://www.shnenglu.com/MatoNo1/comments/commentRss/189969.htmlhttp://www.shnenglu.com/MatoNo1/services/trackbacks/189969.html??a title="[HAOI2007]上升序列 " >[HAOI2007]上升序列
预处理:设F[i]Zi开头的最长上升序列的长度Q怎么求不用说了吧?#8230;…
假设目前需要求长度为M的、标号字典序最的上升序列Q显然其W一个元素A[i]必须满F[i]>=MQ注意,不是{于Q是大于{于Q)Q找到满个条件的最的i卛_。然后,讄前已l求Z该序列的Wx个元素ؓA[y]Q则W?x+1)个元素A[z]需要满的条g是A[z]>A[y]Q且F[z]=F[y]-1Q找到满个条件的最的z即ؓ该序列的W?x+1)个元素。按照这U方法,扫描一遍就可以求出整个序列Q时间复杂度为O(N)。如果整个序列的最长上升序列长?lt;MQ则无解?br />
代码Q?
#include <iostream>
#include 
<stdio.h>
#include 
<stdlib.h>
#include 
<string.h>
using namespace std;
#define re(i, n) for (int i=0; i<n; i++)
#define re1(i, n) for (int i=1; i<=n; i++)
#define re2(i, l, r) for (int i=l; i<r; i++)
#define re3(i, l, r) for (int i=l; i<=r; i++)
#define rre(i, n) for (int i=n-1; i>=0; i--)
#define rre1(i, n) for (int i=n; i>0; i--)
#define rre2(i, r, l) for (int i=r-1; i>=l; i--)
#define rre3(i, r, l) for (int i=r; i>=l; i--)
#define ll long long
const int MAXN = 10010,    MAXM = 1010, INF = ~0U >> 2;
int n, m, len, A[MAXN], F[MAXN], D[MAXN], res[MAXM];
void prepare()
{
    D[len 
= 0= INF; int l, r, mid;
    rre(i, n) 
if (A[i] < D[len]) D[F[i] = ++len] = A[i]; else {
        l 
= 0; r = len;
        
while (l < r) {
            mid 
= l + r + 1 >> 1;
            
if (A[i] < D[mid]) l = mid; else r = mid - 1;
        }
        F[i] 
= l + 1; D[l + 1= A[i];
    }
}
void solve()
{
    
int x, y;
    re(i, n) 
if (F[i] >= m) {
        res[
0= A[i]; if (m == 1return; x = m - 1; y = 1;
        re2(j, i
+1, n) if (F[j] >= x && A[j] > res[y - 1]) {res[y++= A[j]; if (y == m) returnelse x--;}
    }
}
int main()
{
    scanf(
"%d"&n); re(i, n) scanf("%d"&A[i]);
    prepare();
    
int m_s; scanf("%d"&m_s);
    re(i, m_s) {scanf(
"%d"&m); if (m > len) puts("Impossible"); else {solve(); re(j, m-1) printf("%d ", res[j]); printf("%d\n", res[m - 1]);}}
    
return 0;
}


??a title="[HAOI2006]数字序列 " >[HAOI2006]数字序列
首先Q由于序列的所有元素都是整敎ͼ所以可以将原序列的所有元素减d的下标,q样把上升序列转化Z下降序列了?br />W一问的l果昄是(N-新序列的最长不下降序列长度)。关键在于第二问。以下A均表C新序列?br />设F[i]ZA[i]l尾的最长不下降序列长度Q同P求法不用说了Q,G[i]为在A[i]不修改的前提下将A[0..i]转变Z下降序列的最修攚w。首先求出F[i]Q然后在求G[i]Ӟ枚D上一?#8220;不动?#8221;Q就是不修改的元素)A[j]Q显然必LA[j]<=A[i]且F[j]=F[i]-1Q,q样最修攚w是G[j]+(A[j..i]转变Z下降序列的最修攚wQ。可以证明,A[j..i]的最优修Ҏ案必然是A[j+1..t]全部修改为A[j]QA[t+1..i]全部修改为A[i]Q这里t是一个[j..i]范围的倹{问题就是如何求出最优的tQ?br />一开始,假设t=jQ即把A[j+1..i-1]全部修改为A[i]Q计出修改量,设ؓS。然后,׃A[j+1..i-1]之间的元素要么小于A[j]Q要么大于A[i]Q这个是昄的囧Q,我们把小于A[j]的元素称?#8220;数”Q把大于A[i]的元素称?#8220;大数”Q则当t取t0Ӟ修改量ؓS-(A[i]-A[j])*(A[j+1..t0]中的“数”个数减去“大数”个数Q。这P只需扫描一下,求出使得(A[j+1..t0]中的“数”个数减去“大数”个数Q值最大的t0卛_?br />当然q有一个问题,对于同一个iQ满?#8220;A[j]<=A[i]且F[j]=F[i]-1”的元素个数可能有很多Q如果一个一个枚举,一个一个扫描,会很慢的?#8230;…解决Ҏ是,求出满q个条g的j中最的一个,设ؓj0Q然后把A[j0+1..i-1]中的所?#8220;数”?#8220;大数”全部处理出来Q然后用cM前缀和的Ҏp搞了?#8230;…当然Qؓ了找到j0Q需要徏一个二分图Q边?F[i], i)?br />最后,Z方便Q可以把A序列的左边加一?INFQ右边加一?INF。最后ȝ旉复杂度,理论上ؓO(N2)Q但׃是随机数据,所以远q达不到q个U别?br />
代码Q?
#include <iostream>
#include 
<stdio.h>
#include 
<stdlib.h>
#include 
<string.h>
using namespace std;
#define re(i, n) for (int i=0; i<n; i++)
#define re1(i, n) for (int i=1; i<=n; i++)
#define re2(i, l, r) for (int i=l; i<r; i++)
#define re3(i, l, r) for (int i=l; i<=r; i++)
#define rre(i, n) for (int i=n-1; i>=0; i--)
#define rre1(i, n) for (int i=n; i>0; i--)
#define rre2(i, r, l) for (int i=r-1; i>=l; i--)
#define rre3(i, r, l) for (int i=r; i>=l; i--)
#define ll long long
const int MAXN = 40010, INF = ~0U >> 2;
struct edge {
    
int a, b, pre, next;
} E[MAXN 
<< 1];
int n, m, A[MAXN], D[MAXN], F[MAXN], W[MAXN], res1;
ll G[MAXN], res2;
void init_d()
{
    re(i, n) E[i].pre 
= E[i].next = i; m = n;
}
void add_edge(int a, int b)
{
    E[m].a 
= a; E[m].b = b; E[m].pre = E[a].pre; E[m].next = a; E[a].pre = m; E[E[m].pre].next = m++;
}
void init()
{
    scanf(
"%d"&n);
    A[
0= -INF; re1(i, n) {scanf("%d"&A[i]); A[i] -= i;} A[++n] = INF; n++;
}
void solve()
{
    init_d(); F[
0= 0; G[0= 0; D[0= -INF; add_edge(00); int len = 0, l, r, mid, x, maxw; ll sum, tmp;
    re2(i, 
1, n) {
        
if (A[i] >= D[len]) D[F[i] = ++len] = A[i]; else {
            l 
= 0; r = len;
            
while (l < r) {
                mid 
= l + r + 1 >> 1;
                
if (A[i] >= D[mid]) l = mid; else r = mid - 1;
            }
            D[F[i] 
= ++l] = A[i];
        }
        
for (int p=E[F[i]-1].next; ; p=E[p].next) if (A[i] >= A[x = E[p].b]) break;
        W[x] 
= 0; re2(j, x+1, i) if (A[j] < A[i]) W[j] = W[j - 1+ 1else W[j] = W[j - 1- 1;
        sum 
= 0; maxw = -INF; G[i] = ~0Ull >> 2;
        rre2(j, i, x) {
            
if (A[j] <= A[i] && F[j] == F[i] - 1) {
                tmp 
= G[j] + sum; if (tmp < G[i]) G[i] = tmp;
                tmp 
= G[j] + sum - (ll) (maxw - W[j]) * (A[i] - A[j]); if (tmp < G[i]) G[i] = tmp;
            }
            
if (A[j] > A[i]) sum += A[j] - A[i]; else sum += A[i] - A[j];
            
if (W[j] > maxw) maxw = W[j];
        }
        add_edge(F[i], i);
    }
    res1 
= n - F[n - 1- 1; res2 = G[n - 1];
}
void pri()
{
    cout 
<< res1 << endl << res2 << endl;
}
int main()
{
    init();
    solve();
    pri();
    
return 0;
}




Mato_No1 2012-09-08 20:40 发表评论
]]>
【AHOI2013复仇】ZJOI2008 骑士 题解http://www.shnenglu.com/MatoNo1/archive/2012/09/01/189006.htmlMato_No1Mato_No1Sat, 01 Sep 2012 09:03:00 GMThttp://www.shnenglu.com/MatoNo1/archive/2012/09/01/189006.htmlhttp://www.shnenglu.com/MatoNo1/comments/189006.htmlhttp://www.shnenglu.com/MatoNo1/archive/2012/09/01/189006.html#Feedback0http://www.shnenglu.com/MatoNo1/comments/commentRss/189006.htmlhttp://www.shnenglu.com/MatoNo1/services/trackbacks/189006.html原题地址
本沙茶的W一个无向环套树模型Q纪念一?#8230;…

环套树,指的是每个连通块中点数都{于Ҏ的无向图Q称为无向环套树Q或者是每个Ҏ且只有一个前(UCؓ内向环套树)或后l(UCؓ外向环套树)的有向图Q由于这个图的每个连通块当中有且只有一个环Q注意,可能是自环,即长度ؓ1的环Q,且这个环上的每个炚w可以当作根引Z|Q所以叫“环套?#8221;?br />
对于无向环套树,先将整个图进行一ơDFSQ当中如果发现有逆向边(q条边第一ơ被发现必然是作为逆向边的Q也是L是终点的后代Q,p明找Cq个环,记录其v点和l点Q注意,如果有多个连通块的话Q不能退出,要l遍历完Q,再不断上溯(因此在DFSq程中当然要记录父边了囧Q,可以找到整个环了,然后再以环上的结点ؓ根徏树即可,q样依次处理每个q通块?br />
对于内向环套树(外向cMQ,扄更ؓ单,只需要Q选一个点Q不断去扑֮的前,同时记录扑ֈ的点序列Q直到某个点在序列中出现两次为止Q此时这个点以及序列中它两次出现的位|中间的所有点Q就是环上的点,序也顺便记录下来,然后树也不用ZQ直接在原图中找p了?br />
对于q题Q由于每个点都有且只有一个后l,所以是外向环套树,不过本沙茶更們֐于它的基图(无向图,是无向环套树Q,然后是一个DP了囧……

代码Q?
#include <iostream>
#include 
<stdio.h>
#include 
<stdlib.h>
#include 
<string.h>
using namespace std;
#define re(i, n) for (int i=0; i<n; i++)
#define re1(i, n) for (int i=1; i<=n; i++)
#define re2(i, l, r) for (int i=l; i<r; i++)
#define re3(i, l, r) for (int i=l; i<=r; i++)
#define rre(i, n) for (int i=n-1; i>=0; i--)
#define rre1(i, n) for (int i=n; i>0; i--)
#define rre2(i, r, l) for (int i=r-1; i>=l; i--)
#define rre3(i, r, l) for (int i=r; i>=l; i--)
#define ll long long
const int MAXN = 1000010;
const ll INF = ~0Ull >> 2;
struct edge {
    
int a, b, pre, next;
} E0[MAXN 
* 3], E[MAXN << 1];
int n, m0, m, A[MAXN], stk[MAXN], st[MAXN], pr[MAXN], Q[MAXN];
ll F[MAXN][
2], res = 0;
bool vst[MAXN], vst0[MAXN];
void init_d()
{
    re(i, n) E0[i].pre 
= E0[i].next = E[i].pre = E[i].next = i; if (n & 1) m0 = n + 1else m0 = n; m = n;
}
void add_edge0(int a, int b)
{
    E0[m0].a 
= a; E0[m0].b = b; E0[m0].pre = E0[a].pre; E0[m0].next = a; E0[a].pre = m0; E0[E0[m0].pre].next = m0++;
    E0[m0].a 
= b; E0[m0].b = a; E0[m0].pre = E0[b].pre; E0[m0].next = b; E0[b].pre = m0; E0[E0[m0].pre].next = m0++;
}
void add_edge(int a, int b)
{
    E[m].a 
= a; E[m].b = b; E[m].pre = E[a].pre; E[m].next = a; E[a].pre = m; E[E[m].pre].next = m++;
}
void init()
{
    scanf(
"%d"&n); int x; init_d();
    re(i, n) {
        scanf(
"%d%d"&A[i], &x); add_edge0(--x, i);
    }
}
void sol0(int x)
{
    Q[
0= x; int i, j, front, rear;
    
for (front=0, rear=0; front<=rear; front++) {
        i 
= Q[front];
        
for (int p=E0[i].next; p != i; p=E0[p].next) {
            j 
= E0[p].b;
            
if (!vst0[j]) {Q[++rear] = j; vst0[j] = 1; add_edge(i, j);}
        }
    }
    rre3(z, rear, 
0) {
        i 
= Q[z];
        F[i][
0= 0; F[i][1= A[i];
        
for (int p=E[i].next; p != i; p=E[p].next) {
            j 
= E[p].b; F[i][0+= F[j][0>= F[j][1? F[j][0] : F[j][1]; F[i][1+= F[j][0];
        }
    }
}
void solve()
{
    re(i, n) {vst[i] 
= vst0[i] = 0; st[i] = E0[i].next;} int x, y, tp, x0, y0; bool FF, FF2; ll tmp0, tmp1, tmp00, tmp01, res0;
    re(i, n) 
if (!vst[i]) {
        stk[tp 
= 0= i; vst[i] = 1; FF2 = 0;
        
while (tp >= 0) {
            x 
= stk[tp]; FF = 0;
            
for (int p=st[x]; p != x; p=E0[p].next) {
                y 
= E0[p].b;
                
if (!vst[y]) {vst[y] = 1; stk[++tp] = y; pr[y] = p; st[x] = E0[p].next; FF = 1break;}
                
else if (p != (pr[x] ^ 1&& !FF2) {FF2 = 1; x0 = x; y0 = y;}
            }
            
if (!FF) tp--;
        }
        
if (FF2) {
            tp 
= 0; vst0[y0] = 1while (x0 != y0) {stk[tp++= x0; vst0[x0] = 1; x0 = E0[pr[x0]].a;} stk[tp++= y0;
            re(j, tp) sol0(stk[j]);
            tmp0 
= F[stk[0]][0]; tmp1 = -INF;
            re2(j, 
1, tp) {
                tmp00 
= (tmp0 >= tmp1 ? tmp0 : tmp1) + F[stk[j]][0];
                tmp01 
= tmp0 + F[stk[j]][1];
                tmp0 
= tmp00; tmp1 = tmp01;
            }
            res0 
= tmp0 >= tmp1 ? tmp0 : tmp1;
            tmp0 
= -INF; tmp1 = F[stk[0]][1];
            re2(j, 
1, tp) {
                tmp00 
= (tmp0 >= tmp1 ? tmp0 : tmp1) + F[stk[j]][0];
                tmp01 
= tmp0 + F[stk[j]][1];
                tmp0 
= tmp00; tmp1 = tmp01;
            }
            res 
+= res0 >= tmp0 ? res0 : tmp0;
        }
    }
}
void pri()
{
    cout 
<< res << endl;
}
int main()
{
    init();
    solve();
    pri();
    
return 0;
}




Mato_No1 2012-09-01 17:03 发表评论
]]>
XOR专题Q一Q:异或方程l的解法http://www.shnenglu.com/MatoNo1/archive/2012/05/20/175404.htmlMato_No1Mato_No1Sun, 20 May 2012 02:17:00 GMThttp://www.shnenglu.com/MatoNo1/archive/2012/05/20/175404.htmlhttp://www.shnenglu.com/MatoNo1/comments/175404.htmlhttp://www.shnenglu.com/MatoNo1/archive/2012/05/20/175404.html#Feedback3http://www.shnenglu.com/MatoNo1/comments/commentRss/175404.htmlhttp://www.shnenglu.com/MatoNo1/services/trackbacks/175404.html阅读全文

Mato_No1 2012-05-20 10:17 发表评论
]]>
炮兵阵地以及与其相关的一cȝ压DP问题http://www.shnenglu.com/MatoNo1/archive/2012/03/10/167626.htmlMato_No1Mato_No1Sat, 10 Mar 2012 15:27:00 GMThttp://www.shnenglu.com/MatoNo1/archive/2012/03/10/167626.htmlhttp://www.shnenglu.com/MatoNo1/comments/167626.htmlhttp://www.shnenglu.com/MatoNo1/archive/2012/03/10/167626.html#Feedback0http://www.shnenglu.com/MatoNo1/comments/commentRss/167626.htmlhttp://www.shnenglu.com/MatoNo1/services/trackbacks/167626.html原题地址
说实话我W一ơ尝试写炮兵阵地是在2009q?#8230;…已经q去两年多了Q终于找C一个好的解?#8230;…庆祝一?#8230;…

【状态压~DP?br />所谓状态压~DPQ就是对于某些DP问题Q每一阶段的状态都有很多维Q要利用某些手段它们压~到一l_一个正整数Q,Zq行状态的_Q去掉不合法的状态)Q然后再q行DP。这里讲的主要是传统的状压DPQ有一U基?#8220;插头”的DPQ更高Q以后再搞?br />对于本题Q可以设计出一个这L状态:[0..1][0..1][0..1]...[0..1]Q有M个[0..1]Q,表示该行的每个格子放不放炮兵Q如果放Qؓ1Q否则ؓ0。显Ӟq是一个M位二q制敎ͼ如果能把它们压羃成一个int好了?br />
【如何压~?br />W一个问题是q么多维的状态如何压~的问题?br />对于本题Q由于是二进制数Q直接压~就可以了。但是对于某些情况,状态是个三q制敎ͼ每个格子的属性都?U)甚至更多q制敎ͼq样Q直接压~会D无法使用位运,从而“解压”变得很麻烦,耗时也很长(需要暴力)Q因此,可以每位三q制都拆成两位二q制Q?br />0->00
1->01
2->10
Q当?拆成10?拆成11也木有问题,只要能区分开p了)
q样Q每个状态就可以?个二q制数来表示Q可以在构造出所有合法状态以后将每个状态所对应的两位二q制数存到struct里面Q用时调出卛_?br />
【如何精?br />q个问题是最重要的,因ؓQ如果不_Q在枚D状态以及{Uȝ时候就会枚丑ֈ很多不合法状态,D旉费?br />所谓精Q是指在预处理以及DPq程中,量避开不合法状态?br />Q?Q预处理中的_Q?br />包括3个部分:
<1>扑ֈ所有可能的合法状态ƈ~号Q根据题意限Ӟ有的状态在阶段内就不合法(比如本题Q一行一阶段Q那么凡是有两个1位的距离于2的状态都不合法)Q而且q种状态所占的比重往往q很大(本题中,M=10Ӟ也只?0U可能的合法状态)Q此ӞZ扑ֈq些合法状态,可以DFS构造实现?br />需要注意的是,有的题不光要扑ֈ一个阶D内的合法状态,q要扑ֈ两个或两个以上阶D内的合法状态(比如那个有关多米诺骨牌的题)Q此旉要两个int同时DFSQ?br />在找到合法状态以后,需要对每个合法状态进行编P以达?#8220;压羃”的目的。这里就涉及C状态编号和状态表C的问题Q比如,状?001Q表CZؓ9Q在DFS中第一个被搜到Q因此编号ؓ0Q不要搞混了q两个(其不要搞؜“~号?”?#8220;状态表CZؓ0”Q它们是不同的)。在预处理和DP的过E中Q所有涉及到状态的数组下标Q全部是~号而不是表C,知道~号要求表示Q可以在DFS中记录的数组里面调,而知道表C求编P可以利用逆数l或者哈希;
<2>扑ֈ每一阶段的合法状态:即?lt;1>中被判定为合法的状态,在具体的各个阶段中也未必合法Q比如本题,如果某一行的某一个位|是'H'Q不能放Q而某一个状态在q里放了Q则不合法)Q因此要Ҏ个阶D再枚D一遍,扑ֈ真正合法的状态,q计入一个vectorQ?br /><3>扑ֈ状态{UM的合法状态:在状态{UMQ往往要求状态不冲突Q比如本题,在连l的三个阶段中,都不能有某一位有两个?的情况)Q因此,q要枚D每个状态在转移时与其不冲突的状态,q计入vector?br />注意Q有时候这一步不是很Ҏq行Q需要在DPq程中进行;
Q?QDPq程中的_Q?br />DPq程中,枚D状态、{Ud{都只枚丑֐法的Q在vector里面调(注意vector里记录的全都是状态编可不是表C!Q,可以大大减少枚D量,不过有时候,q会有一些时间浪费,q时候,可以采取一些其它的办法来精Q比如再ơ进行DFS构造合法状态等?br />
MQ这c问题的目标是“_Q精Q再_Q枚D到的不合法状态减到最?#8221;?br />代码Q?br />
#include <iostream>
#include 
<stdio.h>
#include 
<stdlib.h>
#include 
<string.h>
#include 
<vector>
using namespace std;
#define re(i, n) for (int i=0; i<n; i++)
#define re1(i, n) for (int i=1; i<=n; i++)
#define re2(i, l, r) for (int i=l; i<r; i++)
#define re3(i, l, r) for (int i=l; i<=r; i++)
#define rre(i, n) for (int i=n-1; i>=0; i--)
#define rre1(i, n) for (int i=n; i>0; i--)
#define rre2(i, r, l) for (int i=r-1; i>=l; i--)
#define rre3(i, r, l) for (int i=r; i>=l; i--)
#define pb push_back
#define IR iterator
typedef vector 
<int> vi;
const int MAXN = 103, MAXM = 11, MAXS = 100, INF = ~0U >> 2;
int n, m, S, A[MAXN], B[MAXS], T1[MAXS], F[MAXN][MAXS][MAXS], res;
bool F0[MAXN][MAXS];
vi P0[MAXN], P1[MAXS][MAXS];
void init()
{
     scanf(
"%d%d"&n, &m); getchar();
     re1(i, n) {A[i] 
= 0; re(j, m) A[i] |= ((getchar() == 'P'<< j); getchar();}
}
void dfs(int v, int ST)
{
    
if (v >= m) B[S++= ST; else {dfs(v + 3, ST | (1 << v)); dfs(v + 1, ST);}
}
void prepare()
{
    S 
= 0; dfs(00);
    re(i, S) {T1[i] 
= 0for (int j=B[i]; j; j-=j&(-j)) T1[i]++;}
    re1(i, n) re(j, S) 
if (!(~A[i] & B[j])) {P0[i].pb(j); F0[i][j] = 1;} P0[0].pb(S - 1); F0[0][S - 1= 1;
    re(i, S) re(j, S) 
if (!(B[i] & B[j])) re(k, S) if (!(B[i] & B[k]) && !(B[j] & B[k])) P1[i][j].pb(k);
}
void solve()
{
    re3(i, 
0, n) re(j1, S) re(j2, S) F[i][j1][j2] = -INF; F[0][S - 1][S - 1= 0;
    vi::IR vi_e0, vi_e1, vi_e2; 
int j0, j1, k, V;
    re(i, n) {
        vi_e0 
= P0[i].end(); if (i) vi_e1 = P0[i - 1].end(); else vi_e1 = P0[i].end();
        
for (vi::IR p=P0[i].begin(); p != vi_e0; p++)
            
for (vi::IR p_=P0[i ? i - 1 : i].begin(); p_ != vi_e1; p_++) {
                j0 
= *p; j1 = *p_;
                
if (!(B[j0] & B[j1])) {
                    vi_e2 
= P1[j0][j1].end();
                    
for (vi::IR p__ = P1[j0][j1].begin(); p__ != vi_e2; p__++) {
                        k 
= *p__;
                        
if (F0[i + 1][k]) {
                            V 
= F[i][j0][j1] + T1[k];
                            
if (V > F[i + 1][k][j0]) F[i + 1][k][j0] = V;
                        }
                    }
                }
            }
    }
    res 
= 0; re(i, S) re(j, S) if (F[n][i][j] > res) res = F[n][i][j];
}
void pri()
{
     printf(
"%d\n", res);
}
int main()
{
    init();
    prepare();
    solve();
    pri();
    
return 0;
}


Mato_No1 2012-03-10 23:27 发表评论
]]>
U段树操作极品题——HDU2871http://www.shnenglu.com/MatoNo1/archive/2011/12/18/162313.htmlMato_No1Mato_No1Sun, 18 Dec 2011 00:58:00 GMThttp://www.shnenglu.com/MatoNo1/archive/2011/12/18/162313.htmlhttp://www.shnenglu.com/MatoNo1/comments/162313.htmlhttp://www.shnenglu.com/MatoNo1/archive/2011/12/18/162313.html#Feedback0http://www.shnenglu.com/MatoNo1/comments/commentRss/162313.htmlhttp://www.shnenglu.com/MatoNo1/services/trackbacks/162313.html原题地址
q是一道线D|操作的极品题Q因为它?个操作刚好覆盖了U段树操作问题的3U处理思\Q可以说是把U段树操作的全部内容都包含进M?br />
U段树是一U静态的数据l构Q因Z늺D|一旦徏成,其Ş态就永远不会发生变化Q改变的仅仅是结点上记录的各U信息的倹{因此,对于U段树操作,核心问题也就是如何维护和处理q些信息。ȝ来说Q对于线D|l点信息的维护和处理Q有以下3U基本思\Q?br />Q?Q左叛_中型Q?br />所谓左叛_中,是用左叛_l点存储的信息来得到父结点存储的信息的|q是最常见的线D|l护Ҏ。D一些简单的例子Q比如结点的SUM域表Cl点区间上所有元素的和,那么q个域维护的Ҏ是“父结点SUM=左子l点SUM+叛_l点SUM”Q再比如l点的MAX/MIN域表Cl点区间上所有元素的最?|那么l护Ҏ是“父结点MAX/MIN=max/min{左子l点MAX/MIN,叛_l点MAX/MIN}”。这U维护方法也比较单,只要在每ơ对子结点进行修改之后upd一下就行了Q对于那些自向下递归Q而且涉及到改值的操作Q在递归完左叛_l点后一定要记得upd一下)Q在q之中有一个很重要的思想是“左右q箋D?#8221;思想Q如果题目中要求L一个区间内的具有某U性质的最长的q箋序列Q也是子区_Q比如最长连l上升子序列?1值问题中q箋?D|者非0D(在具体问题中是q箋的空闲段或者占用段Q等Q可以在每个l点上维护三个域QlS、rS和SQ分别表Cl点区间左端Q从区间的最左端开始的Q具有这U性质的最长连l序列的长度Q该l点区间右端Q到区间的最右端l束的)hq种性质的最长连l序列的长度和该区间内具有这U性质的最长连l序列的长度Q也是要求的那个东东)Q则l护Ҏ?#8220;父结点lS=左子l点lSQ左子结点lS<左子l点lenQ或左子l点len+叛_l点lSQ左子结点lS=左子l点lenQ,父结点rScMQ父l点S=max{左子l点S,叛_l点S,左子l点rS+叛_l点lS}”Q此外,׃要求的这个区间可能被拆成多个q箋的结点区_因此需要按序合ƈq些区间Q合q的Ҏ是:讄S0和S1QS0表示不保证能延下去的区间长度,S0=上一个区间的S1+本区间的lSQS1表示可以延下去的区间长度,S1=上一个区间的S1+本区间lenQ如果本区间整个都是满条g的,即S=lenQ或本区间的rSQ本区间不都是满x件的Q即S<lenQ,取过E中所有S0和区间S的最大值即为结果?br />在HDU2871中,应用左右归中的方法维护的信息是“最长连l空闲段”的长度,New操作需要;

Q?Q调整边界型Q?br />考虑q样一个问题:现在要插入、删除一些[0, 100000)的整敎ͼq且在此q程中不断询问第K的整数是多,怎么办?q树可以实玎ͼ但线D|昄是更好的Ҏ。对每个l点Q存储一个K0DCZ于该l点区间内的整数的个敎ͼ则查扄K的时候只需要不断执行以下操作:Kth(A, K)Q表C在l点A代表的区间内扄K的Q然后,若K<=l点A的左子结点K0|则执行Kth(A的左子结? K)Q否则执行Kth(A的右子结? K-A左子l点的K0)Q这和^衡树似Q,直到扑ֈ叶结点ؓ止。这U方法称?#8220;调整边界?#8221;Q即随着l点深入Q不断羃(自顶向下Q或扩大Q自底向上)范围Q最后找到结果。像扄K这L操作属于自顶向下型,而像“扑ֈX所在的h某种性质的最长的q箋区间”属于自底向上型Q注意和本题的Free不一PQ?br />
Q?Q标记辅助型Q?br />q种l护信息的方法,特点是利用标记来l护信息Q即对于某些l点Q主要是叶结点,因ؓ其标C再下放)Q直接用标记来得到一些数据,比如对于HDU2871q一题,其中对于叶结点位于的插入U段的标P使用的就是标记?br />
下面是本?个操作的具体实现Q?br /><1>U段树结点定义:
本题需要两늺D|Q这是因为New与Free操作对于tot域(插入U段左端点的M敎ͼ会造成不同的媄响,具体来说Q在New操作中,totg会被同时加上Q需要另外一个操作加上)Q然而在Free操作中,totg被同时清I,q样׃D在对某个l点清空Q该l点包含在某个Free操作要清I的U段中)q打?标记之后Q如果紧接着又插入一条包含这个结点区间的新线D,则这个结点的0标记׃丧失Q这样在紧接着下传的时候,其子l点的tot值就不会被清I(事实上已l被清空了)。所以,tot域彻底{Ud另一늺D|里?
struct node {
    
int len, mr, lsc, rsc, sc;
} T[MAXN 
<< 2];
struct node0 {
    
int tot;
    
bool mr;
} T0[MAXN 
<< 2];
其中lsc、rsc、sc是q箋I闲D늚长度Q用左右归中的方法维护)Qmr是一个整体赋值标讎ͼ在T中,mr的D?1表示无标讎ͼ未被整体赋|Q若?表示被整体清I,若大?表示整体被一条线D覆盖,mr值就是这条线D늚~号Qؓ区分不同U段Q这里按照输入顺序对每一条New操作插入的线D以1?……~号Q,在T0中,mr=1表示在Reset中被整体清空Qmr=0表示无标记?br /><2>操作处理Q?br />1)Reset操作Q将T、T0的根l点打上清空标记卛_Q?br />2)NewQ涉及到两个操作Q分别是找最左的长度为x的连l空闲段Q以及插入一条线Dc对于前者,可以Ҏlsc、rsc、sc的|按照“先左子结点,再跨两个子l点Q最后右子结?#8221;的顺序求得(详见代码Q;对于后者就不用说了Q太Ҏ实现了(注意标记的处理以及updQ另外要插入一个totQ;
3)FreeQ也涉及两个操作Q分别是找一个点x所在的U段Q插入过的线D)长度以及删除一条线D,对于前者可New插入q的所有线D늚左右端点预存hQ然后找C表区间[x, x]的结点的mr|也就是结点x被编号ؓ马的线D覆盖)Q再在预存的U段中找到即可。对于后者,直接清空卛_Q不要在T0中打标记Q而要单独删除一个totQ;
4)GetQ直接利用T0中的tot扑ֈWK的值即可;

代码

Mato_No1 2011-12-18 08:58 发表评论
]]>
划分?/title><link>http://www.shnenglu.com/MatoNo1/archive/2011/06/27/149604.html</link><dc:creator>Mato_No1</dc:creator><author>Mato_No1</author><pubDate>Mon, 27 Jun 2011 12:54:00 GMT</pubDate><guid>http://www.shnenglu.com/MatoNo1/archive/2011/06/27/149604.html</guid><wfw:comment>http://www.shnenglu.com/MatoNo1/comments/149604.html</wfw:comment><comments>http://www.shnenglu.com/MatoNo1/archive/2011/06/27/149604.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.shnenglu.com/MatoNo1/comments/commentRss/149604.html</wfw:commentRss><trackback:ping>http://www.shnenglu.com/MatoNo1/services/trackbacks/149604.html</trackback:ping><description><![CDATA[首先QOrz一下AHdoc犇Q本沙茶是看他的ȝ才搞懂划分树的?br /><a title="原文地址" >原文地址</a><br /><br />划分树,是每个l点代表一个序列,设这个序列的长度为lenQ若len>1Q则序列中前len/2Q上取整Q这里数学公式不好打Q真囧)个元素被分到左子l点Q左子结点代表的序列是q些元素<span style="color: red"><strong>按照根结点中的顺?/strong></span>l成的序列,而剩下的元素被分到右子结点,叛_l点代表的序列也是剩下的元素按照根l点中的序l成的序列;若len=1Q则该结点ؓ叶结炏V划分树最重要的应用就是找区间WK(只是查找Q不包括修改Q?br /><br />写划分树时主要有两个函数Q徏树和扑֌间第K。由于后者AHdoc犇已经ȝ了,所以这里只ȝ建树的函数?br /><br />讄前结点ؓ[l..r]Ql<rQ就是目前的l点是原序列不断划分后得到[l..r]q一D,其实也就是a0[l..r]打ؕ序后得到的Qa0为原序列递增排序后的序列Q首先找C|是a0[mid]Qmid=l+r>>1。然后可以得刎ͼ[l..r]中小于中值的的元素一定被划分到左子结点,[l..r]中大于中值的元素一定被划分到右子结点,而[l..r]中等于中值的元素则不定Q有的被划分到左子结点,有的被划分到叛_l点Q这需要先扑ֈ应被划分到左子结点的{于中值的元素个数smQ从mid开始不断往左,直到扑ֈ边界处或者找C个小于中值的元素为止Q或者说Qsm是a0[l..mid]中等于中值的元素个数Q,然后开始划分,于中值分到左子结点,大于中值分到右子结点,{于中值的Q若目前q没满sm则分到左子结点否则分到右子结炏V另外中间有两个值需要记录(扑֌间第K时必须要用刎ͼQsl和sr。sl[i]表示[l..i]中被分到左子l点的元素个敎ͼsr[i]表示[l..i]中被分到叛_l点的元素个敎ͼq里l<=i<=r。显然sl[i]+sr[i]=i-l+1Q其实sr[i]可以不用记录的,q里只是Z在找WK操作中减少计算ơ数Qv到空间换旉的作用)?br />建树代码Q? <div style="border-right: #cccccc 1px solid; padding-right: 5px; border-top: #cccccc 1px solid; padding-left: 4px; font-size: 13px; padding-bottom: 4px; border-left: #cccccc 1px solid; width: 98%; word-break: break-all; padding-top: 4px; border-bottom: #cccccc 1px solid; background-color: #eeeeee"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #0000ff">int</span><span style="color: #000000"> mkt(</span><span style="color: #0000ff">int</span><span style="color: #000000"> l, </span><span style="color: #0000ff">int</span><span style="color: #000000"> r, </span><span style="color: #0000ff">int</span><span style="color: #000000"> d)<br />{<br />    T[</span><span style="color: #000000">++</span><span style="color: #000000">No].l </span><span style="color: #000000">=</span><span style="color: #000000"> l; T[No].r </span><span style="color: #000000">=</span><span style="color: #000000"> r; </span><span style="color: #0000ff">int</span><span style="color: #000000"> mid </span><span style="color: #000000">=</span><span style="color: #000000"> l </span><span style="color: #000000">+</span><span style="color: #000000"> r </span><span style="color: #000000">>></span><span style="color: #000000"> </span><span style="color: #000000">1</span><span style="color: #000000">; T[No].mid </span><span style="color: #000000">=</span><span style="color: #000000"> mid;<br />    </span><span style="color: #0000ff">if</span><span style="color: #000000"> (l </span><span style="color: #000000">==</span><span style="color: #000000"> r) </span><span style="color: #0000ff">return</span><span style="color: #000000"> No;<br />    </span><span style="color: #0000ff">int</span><span style="color: #000000"> midv </span><span style="color: #000000">=</span><span style="color: #000000"> a0[mid], sm </span><span style="color: #000000">=</span><span style="color: #000000"> mid </span><span style="color: #000000">-</span><span style="color: #000000"> l </span><span style="color: #000000">+</span><span style="color: #000000"> </span><span style="color: #000000">1</span><span style="color: #000000">; rre2(i, mid, l) </span><span style="color: #0000ff">if</span><span style="color: #000000"> (a0[i] </span><span style="color: #000000"><</span><span style="color: #000000"> midv) {sm </span><span style="color: #000000">=</span><span style="color: #000000"> mid </span><span style="color: #000000">-</span><span style="color: #000000"> i; </span><span style="color: #0000ff">break</span><span style="color: #000000">;}<br />    </span><span style="color: #0000ff">int</span><span style="color: #000000"> x </span><span style="color: #000000">=</span><span style="color: #000000"> l, y </span><span style="color: #000000">=</span><span style="color: #000000"> mid </span><span style="color: #000000">+</span><span style="color: #000000"> </span><span style="color: #000000">1</span><span style="color: #000000">;<br />    </span><span style="color: #0000ff">if</span><span style="color: #000000"> (a[d][l] </span><span style="color: #000000"><</span><span style="color: #000000"> midv) {<br />        a[d </span><span style="color: #000000">+</span><span style="color: #000000"> </span><span style="color: #000000">1</span><span style="color: #000000">][x</span><span style="color: #000000">++</span><span style="color: #000000">] </span><span style="color: #000000">=</span><span style="color: #000000"> a[d][l]; sl[d][l] </span><span style="color: #000000">=</span><span style="color: #000000"> </span><span style="color: #000000">1</span><span style="color: #000000">; sr[d][l] </span><span style="color: #000000">=</span><span style="color: #000000"> </span><span style="color: #000000">0</span><span style="color: #000000">;<br />    } </span><span style="color: #0000ff">else</span><span style="color: #000000"> </span><span style="color: #0000ff">if</span><span style="color: #000000"> (a[d][l] </span><span style="color: #000000">==</span><span style="color: #000000"> midv </span><span style="color: #000000">&&</span><span style="color: #000000"> sm) {<br />        a[d </span><span style="color: #000000">+</span><span style="color: #000000"> </span><span style="color: #000000">1</span><span style="color: #000000">][x</span><span style="color: #000000">++</span><span style="color: #000000">] </span><span style="color: #000000">=</span><span style="color: #000000"> a[d][l]; sl[d][l] </span><span style="color: #000000">=</span><span style="color: #000000"> </span><span style="color: #000000">1</span><span style="color: #000000">; sr[d][l] </span><span style="color: #000000">=</span><span style="color: #000000"> </span><span style="color: #000000">0</span><span style="color: #000000">; sm</span><span style="color: #000000">--</span><span style="color: #000000">;<br />    } </span><span style="color: #0000ff">else</span><span style="color: #000000"> {<br />        a[d </span><span style="color: #000000">+</span><span style="color: #000000"> </span><span style="color: #000000">1</span><span style="color: #000000">][y</span><span style="color: #000000">++</span><span style="color: #000000">] </span><span style="color: #000000">=</span><span style="color: #000000"> a[d][l]; sl[d][l] </span><span style="color: #000000">=</span><span style="color: #000000"> </span><span style="color: #000000">0</span><span style="color: #000000">; sr[d][l] </span><span style="color: #000000">=</span><span style="color: #000000"> </span><span style="color: #000000">1</span><span style="color: #000000">;<br />    }<br />    re3(i, l</span><span style="color: #000000">+</span><span style="color: #000000">1</span><span style="color: #000000">, r) {<br />        </span><span style="color: #0000ff">if</span><span style="color: #000000"> (a[d][i] </span><span style="color: #000000"><</span><span style="color: #000000"> midv) {<br />            a[d </span><span style="color: #000000">+</span><span style="color: #000000"> </span><span style="color: #000000">1</span><span style="color: #000000">][x</span><span style="color: #000000">++</span><span style="color: #000000">] </span><span style="color: #000000">=</span><span style="color: #000000"> a[d][i]; sl[d][i] </span><span style="color: #000000">=</span><span style="color: #000000"> sl[d][i </span><span style="color: #000000">-</span><span style="color: #000000"> </span><span style="color: #000000">1</span><span style="color: #000000">] </span><span style="color: #000000">+</span><span style="color: #000000"> </span><span style="color: #000000">1</span><span style="color: #000000">; sr[d][i] </span><span style="color: #000000">=</span><span style="color: #000000"> sr[d][i </span><span style="color: #000000">-</span><span style="color: #000000"> </span><span style="color: #000000">1</span><span style="color: #000000">];<br />        } </span><span style="color: #0000ff">else</span><span style="color: #000000"> </span><span style="color: #0000ff">if</span><span style="color: #000000"> (a[d][i] </span><span style="color: #000000">==</span><span style="color: #000000"> midv </span><span style="color: #000000">&&</span><span style="color: #000000"> sm) {<br />            a[d </span><span style="color: #000000">+</span><span style="color: #000000"> </span><span style="color: #000000">1</span><span style="color: #000000">][x</span><span style="color: #000000">++</span><span style="color: #000000">] </span><span style="color: #000000">=</span><span style="color: #000000"> a[d][i]; sl[d][i] </span><span style="color: #000000">=</span><span style="color: #000000"> sl[d][i </span><span style="color: #000000">-</span><span style="color: #000000"> </span><span style="color: #000000">1</span><span style="color: #000000">] </span><span style="color: #000000">+</span><span style="color: #000000"> </span><span style="color: #000000">1</span><span style="color: #000000">; sr[d][i] </span><span style="color: #000000">=</span><span style="color: #000000"> sr[d][i </span><span style="color: #000000">-</span><span style="color: #000000"> </span><span style="color: #000000">1</span><span style="color: #000000">]; sm</span><span style="color: #000000">--</span><span style="color: #000000">;<br />        } </span><span style="color: #0000ff">else</span><span style="color: #000000"> {<br />            a[d </span><span style="color: #000000">+</span><span style="color: #000000"> </span><span style="color: #000000">1</span><span style="color: #000000">][y</span><span style="color: #000000">++</span><span style="color: #000000">] </span><span style="color: #000000">=</span><span style="color: #000000"> a[d][i]; sl[d][i] </span><span style="color: #000000">=</span><span style="color: #000000"> sl[d][i </span><span style="color: #000000">-</span><span style="color: #000000"> </span><span style="color: #000000">1</span><span style="color: #000000">]; sr[d][i] </span><span style="color: #000000">=</span><span style="color: #000000"> sr[d][i </span><span style="color: #000000">-</span><span style="color: #000000"> </span><span style="color: #000000">1</span><span style="color: #000000">] </span><span style="color: #000000">+</span><span style="color: #000000"> </span><span style="color: #000000">1</span><span style="color: #000000">;<br />        }<br />    }<br />    </span><span style="color: #0000ff">int</span><span style="color: #000000"> No0 </span><span style="color: #000000">=</span><span style="color: #000000"> No; T[No0].lch </span><span style="color: #000000">=</span><span style="color: #000000"> mkt(l, mid, d </span><span style="color: #000000">+</span><span style="color: #000000"> </span><span style="color: #000000">1</span><span style="color: #000000">); T[No0].rch </span><span style="color: #000000">=</span><span style="color: #000000"> mkt(mid </span><span style="color: #000000">+</span><span style="color: #000000"> </span><span style="color: #000000">1</span><span style="color: #000000">, r, d </span><span style="color: #000000">+</span><span style="color: #000000"> </span><span style="color: #000000">1</span><span style="color: #000000">); </span><span style="color: #0000ff">return</span><span style="color: #000000"> No0;<br />}<br /></span></div>q里a是每层划分后的序列?br />查找区间WK的代码Q? <div style="border-right: #cccccc 1px solid; padding-right: 5px; border-top: #cccccc 1px solid; padding-left: 4px; font-size: 13px; padding-bottom: 4px; border-left: #cccccc 1px solid; width: 98%; word-break: break-all; padding-top: 4px; border-bottom: #cccccc 1px solid; background-color: #eeeeee"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #0000ff">int</span><span style="color: #000000"> Find_Kth(</span><span style="color: #0000ff">int</span><span style="color: #000000"> l, </span><span style="color: #0000ff">int</span><span style="color: #000000"> r, </span><span style="color: #0000ff">int</span><span style="color: #000000"> K)<br />{<br />    </span><span style="color: #0000ff">int</span><span style="color: #000000"> i </span><span style="color: #000000">=</span><span style="color: #000000"> root, d </span><span style="color: #000000">=</span><span style="color: #000000"> </span><span style="color: #000000">0</span><span style="color: #000000">, l0, r0, mid0, s0, s1;<br />    </span><span style="color: #0000ff">while</span><span style="color: #000000"> (</span><span style="color: #000000">1</span><span style="color: #000000">) {<br />        l0 </span><span style="color: #000000">=</span><span style="color: #000000"> T[i].l, r0 </span><span style="color: #000000">=</span><span style="color: #000000"> T[i].r; mid0 </span><span style="color: #000000">=</span><span style="color: #000000"> T[i].mid;<br />        </span><span style="color: #0000ff">if</span><span style="color: #000000"> (l0 </span><span style="color: #000000">==</span><span style="color: #000000"> r0) </span><span style="color: #0000ff">return</span><span style="color: #000000"> a[d][l];<br />        </span><span style="color: #0000ff">if</span><span style="color: #000000"> (l </span><span style="color: #000000">==</span><span style="color: #000000"> l0) s0 </span><span style="color: #000000">=</span><span style="color: #000000"> l; </span><span style="color: #0000ff">else</span><span style="color: #000000"> s0 </span><span style="color: #000000">=</span><span style="color: #000000"> l0 </span><span style="color: #000000">+</span><span style="color: #000000"> sl[d][l </span><span style="color: #000000">-</span><span style="color: #000000"> </span><span style="color: #000000">1</span><span style="color: #000000">]; s1 </span><span style="color: #000000">=</span><span style="color: #000000"> l0 </span><span style="color: #000000">+</span><span style="color: #000000"> sl[d][r] </span><span style="color: #000000">-</span><span style="color: #000000"> </span><span style="color: #000000">1</span><span style="color: #000000">;<br />        </span><span style="color: #0000ff">if</span><span style="color: #000000"> (K </span><span style="color: #000000"><=</span><span style="color: #000000"> s1 </span><span style="color: #000000">-</span><span style="color: #000000"> s0 </span><span style="color: #000000">+</span><span style="color: #000000"> </span><span style="color: #000000">1</span><span style="color: #000000">) {<br />            i </span><span style="color: #000000">=</span><span style="color: #000000"> T[i].lch; l </span><span style="color: #000000">=</span><span style="color: #000000"> s0; r </span><span style="color: #000000">=</span><span style="color: #000000"> s1; d</span><span style="color: #000000">++</span><span style="color: #000000">;<br />        } </span><span style="color: #0000ff">else</span><span style="color: #000000"> {<br />            K </span><span style="color: #000000">-=</span><span style="color: #000000"> (s1 </span><span style="color: #000000">-</span><span style="color: #000000"> s0 </span><span style="color: #000000">+</span><span style="color: #000000"> </span><span style="color: #000000">1</span><span style="color: #000000">); </span><span style="color: #0000ff">if</span><span style="color: #000000"> (l </span><span style="color: #000000">==</span><span style="color: #000000"> l0) l </span><span style="color: #000000">=</span><span style="color: #000000"> mid0 </span><span style="color: #000000">+</span><span style="color: #000000"> </span><span style="color: #000000">1</span><span style="color: #000000">; </span><span style="color: #0000ff">else</span><span style="color: #000000"> l </span><span style="color: #000000">=</span><span style="color: #000000"> mid0 </span><span style="color: #000000">+</span><span style="color: #000000"> sr[d][l </span><span style="color: #000000">-</span><span style="color: #000000"> </span><span style="color: #000000">1</span><span style="color: #000000">] </span><span style="color: #000000">+</span><span style="color: #000000"> </span><span style="color: #000000">1</span><span style="color: #000000">;<br />            r </span><span style="color: #000000">=</span><span style="color: #000000"> mid0 </span><span style="color: #000000">+</span><span style="color: #000000"> sr[d][r]; i </span><span style="color: #000000">=</span><span style="color: #000000"> T[i].rch; d</span><span style="color: #000000">++</span><span style="color: #000000">;<br />        }<br />    }<br />}<br /></span></div><br />【具体题目?a title="PKU2104" >PKU2104</a>?a title="PKU2761" >PKU2761</a>Q两道Q选一道)<br /><br /> <img src ="http://www.shnenglu.com/MatoNo1/aggbug/149604.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.shnenglu.com/MatoNo1/" target="_blank">Mato_No1</a> 2011-06-27 20:54 <a href="http://www.shnenglu.com/MatoNo1/archive/2011/06/27/149604.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>|络图边表的新表示法:Dancing Link边表Q解决需要删Ҏ删点或改定w的多ơ求最大流问题Q?/title><link>http://www.shnenglu.com/MatoNo1/archive/2011/05/07/145885.html</link><dc:creator>Mato_No1</dc:creator><author>Mato_No1</author><pubDate>Sat, 07 May 2011 06:12:00 GMT</pubDate><guid>http://www.shnenglu.com/MatoNo1/archive/2011/05/07/145885.html</guid><wfw:comment>http://www.shnenglu.com/MatoNo1/comments/145885.html</wfw:comment><comments>http://www.shnenglu.com/MatoNo1/archive/2011/05/07/145885.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.shnenglu.com/MatoNo1/comments/commentRss/145885.html</wfw:commentRss><trackback:ping>http://www.shnenglu.com/MatoNo1/services/trackbacks/145885.html</trackback:ping><description><![CDATA[考虑q样一U网l流问题Q需要对同一个图求多ơ最大流。则在每ơ求最大流之前Q需要将所有边的容量全部恢复到初始|求最大流的过E中Q边的容量fD改变了)。不q这q不最猥琐的,有的时候,我们需要在每次求最大流之前都删d中的一些点或一些边Q或者改变某些原有的边的定wQ特别是需要删Ҏ删边的情늈难搞。因为,一般的边表中边cd定义如下Q?br /> <div style="border-right: #cccccc 1px solid; padding-right: 5px; border-top: #cccccc 1px solid; padding-left: 4px; font-size: 13px; padding-bottom: 4px; border-left: #cccccc 1px solid; width: 98%; word-break: break-all; padding-top: 4px; border-bottom: #cccccc 1px solid; background-color: #eeeeee"><span style="color: #0000ff">struct</span><span style="color: #000000"> edge {<br />        </span><span style="color: #0000ff">int</span><span style="color: #000000"> a, b, f, next;<br />} ed[MAXM </span><span style="color: #000000">+</span><span style="color: #000000"> MAXM];</span></div>表示q条边v点ؓaQ终点ؓbQ容量ؓfQ邻接边Q就是下一条v点ؓa的边Q的~号为next?br />如果要求多次最大流Q那么在每次求最大流之前p把所有边的容量恢复到初始|解决Ҏ是引入一?#8220;初始定w”域fsQ在q条边刚刚被加入的时候将它的fs值和f值都设ؓ初始l它的容量,在恢复时Q只要将所有边的f值恢复到fs卛_。若要改变边定wQ则该边的fs值和f值都设ؓ改变后的定w卛_?br /><br />下面来分析需要删Ҏ删点的情c在q种情况下,如果采用只有next的单向链表,则删除时next域极隑֤理,而且Q在一般的边表中,q设立了表头hdQhd[a]表示边表中v点ؓa的第一条边的编受因此,若删除的?lt;a, b, f>是v点ؓa的第一条边Q还会媄响hd[a]的|使情况变得更为复杂。因此,必须采用双向链表Q还记得Dancing Link么?边表其实也可以搞成Dancing LinkQ方法如下:<br />讑֛中有N个点QM条边Q注意,qM条边只包括正向边Q不包括反向辏V由于每条正向边<a, b, f>都对应一条反向边<b, a, 0>Q因此边表中边的数目其实是M+MQ。首先把边表ed?~Nq?N+1)个位|(下标Q空出来Q作表头Q表头不是边Q因此在遍历边的时候不会遍历到它们Q。其中,ed[0]为总表_用于遍历ed[1..N]中每个未被删ȝ点;ed[1..N]为单点表_ed[i]用来遍历图中所有以iv点的边(和DLX中的二维DL惊h怼Q。然后,若N为偶敎ͼ则空一个位|(也就是将ed[N+1]丢弃不用Q,q是因ؓ我们在增q过E中需要引用到一条边对应的逆向边(正向边对应反向边Q反向边对应正向边)Q一般认为编号ؓp的边对应的逆向Ҏp ^ 1Q这Pp求图中所有正向边的编号都是偶敎ͼ所有反向边的编号都是奇敎ͼ否则会造成混ؕQ。因此当N为偶数时Q?N+1)为奇敎ͼ不能攄W一条正向边Q需要从ed[N+2]开始放|正向边。若N为奇数则不用IZ?br />接下来就是边cd了。在q里Q边cd一共需要包?个域Qa, b, fs, f, pre, nextQ表C条边L为aQ终点ؓbQ初始容量ؓfsQ当前容量ؓfQ上一条v点ؓa的边~号为preQ下一条v点ؓa的边~号为next。注意,和DL一P整个链表是@环的Q也是我们认ؓ表中最后一条v点ؓa的边的下一条邻接边~号是aQ表_Q同Pa的上一条邻接边也就是这条边?br /> <div style="border-right: #cccccc 1px solid; padding-right: 5px; border-top: #cccccc 1px solid; padding-left: 4px; font-size: 13px; padding-bottom: 4px; border-left: #cccccc 1px solid; width: 98%; word-break: break-all; padding-top: 4px; border-bottom: #cccccc 1px solid; background-color: #eeeeee"><span style="color: #0000ff">struct</span><span style="color: #000000"> edge {<br />    </span><span style="color: #0000ff">int</span><span style="color: #000000"> a, b, fs, f, pre, next;<br />} ed[MAXM </span><span style="color: #000000">+</span><span style="color: #000000"> MAXM];</span></div>接下来就是几个重要过E了?br />Q?Q初始化表头Q?br /> <div style="border-right: #cccccc 1px solid; padding-right: 5px; border-top: #cccccc 1px solid; padding-left: 4px; font-size: 13px; padding-bottom: 4px; border-left: #cccccc 1px solid; width: 98%; word-break: break-all; padding-top: 4px; border-bottom: #cccccc 1px solid; background-color: #eeeeee"><span style="color: #0000ff">void</span><span style="color: #000000"> init_d()<br />{<br />    re1(i, n) {ed[i].a </span><span style="color: #000000">=</span><span style="color: #000000"> i; ed[i].b </span><span style="color: #000000">=</span><span style="color: #000000"> </span><span style="color: #000000">-</span><span style="color: #000000">1</span><span style="color: #000000">; ed[i].f </span><span style="color: #000000">=</span><span style="color: #000000"> </span><span style="color: #000000">0</span><span style="color: #000000">; ed[i].pre </span><span style="color: #000000">=</span><span style="color: #000000"> ed[i].next </span><span style="color: #000000">=</span><span style="color: #000000"> i;}<br />    </span><span style="color: #0000ff">if</span><span style="color: #000000"> (n </span><span style="color: #000000">%</span><span style="color: #000000"> </span><span style="color: #000000">2</span><span style="color: #000000">) m </span><span style="color: #000000">=</span><span style="color: #000000"> n </span><span style="color: #000000">+</span><span style="color: #000000"> 1</span><span style="color: #000000">; </span><span style="color: #0000ff">else</span><span style="color: #000000"> m </span><span style="color: #000000">=</span><span style="color: #000000"> n </span><span style="color: #000000">+</span><span style="color: #000000"> 2</span><span style="color: #000000">;<br />}</span></div>q里n是图中的ҎQ相当于NQ,m是边的编h针(相当于DLX中的nodesQ?br />Q?Q添加新边:<br /> <div style="border-right: #cccccc 1px solid; padding-right: 5px; border-top: #cccccc 1px solid; padding-left: 4px; font-size: 13px; padding-bottom: 4px; border-left: #cccccc 1px solid; width: 98%; word-break: break-all; padding-top: 4px; border-bottom: #cccccc 1px solid; background-color: #eeeeee"><span style="color: #0000ff">void</span><span style="color: #000000"> add_edge(</span><span style="color: #0000ff">int</span><span style="color: #000000"> a, </span><span style="color: #0000ff">int</span><span style="color: #000000"> b, </span><span style="color: #0000ff">int</span><span style="color: #000000"> f)<br />{<br />    ed[m].a </span><span style="color: #000000">=</span><span style="color: #000000"> a; ed[m].b </span><span style="color: #000000">=</span><span style="color: #000000"> b; ed[m].fs </span><span style="color: #000000">=</span><span style="color: #000000"> ed[m].f </span><span style="color: #000000">=</span><span style="color: #000000"> f; ed[m].pre </span><span style="color: #000000">=</span><span style="color: #000000"> ed[a].pre; ed[m].next </span><span style="color: #000000">=</span><span style="color: #000000"> a; ed[a].pre </span><span style="color: #000000">=</span><span style="color: #000000"> m; ed[ed[m].pre].next </span><span style="color: #000000">=</span><span style="color: #000000"> m</span><span style="color: #000000">++</span><span style="color: #000000">;<br />    ed[m].a </span><span style="color: #000000">=</span><span style="color: #000000"> b; ed[m].b </span><span style="color: #000000">=</span><span style="color: #000000"> a; ed[m].fs </span><span style="color: #000000">=</span><span style="color: #000000"> ed[m].f </span><span style="color: #000000">=</span><span style="color: #000000"> </span><span style="color: #000000">0</span><span style="color: #000000">; ed[m].pre </span><span style="color: #000000">=</span><span style="color: #000000"> ed[b].pre; ed[m].next </span><span style="color: #000000">=</span><span style="color: #000000"> b; ed[b].pre </span><span style="color: #000000">=</span><span style="color: #000000"> m; ed[ed[m].pre].next </span><span style="color: #000000">=</span><span style="color: #000000"> m</span><span style="color: #000000">++</span><span style="color: #000000">;<br />}</span></div>q个和DLXcMQ不解释了囧……<br /><br />最后进入最核心的部?#8212;—到底如何处理删边或删点?有了DL型边表就爆好搞了Q删M条边Q只要直接删去该边在DL中的位置卛_Q?br /> <div style="border-right: #cccccc 1px solid; padding-right: 5px; border-top: #cccccc 1px solid; padding-left: 4px; font-size: 13px; padding-bottom: 4px; border-left: #cccccc 1px solid; width: 98%; word-break: break-all; padding-top: 4px; border-bottom: #cccccc 1px solid; background-color: #eeeeee"><span style="color: #0000ff">void</span><span style="color: #000000"> deledge(</span><span style="color: #0000ff">int</span><span style="color: #000000"> No)<br />{<br />    ed[ed[No].pre].next </span><span style="color: #000000">=</span><span style="color: #000000"> ed[No].next; ed[ed[No].next].pre </span><span style="color: #000000">=</span><span style="color: #000000"> ed[No].pre;<br />}<br /></span></div>恢复一条已删去的边Q?br /> <div style="border-right: #cccccc 1px solid; padding-right: 5px; border-top: #cccccc 1px solid; padding-left: 4px; font-size: 13px; padding-bottom: 4px; border-left: #cccccc 1px solid; width: 98%; word-break: break-all; padding-top: 4px; border-bottom: #cccccc 1px solid; background-color: #eeeeee"><span style="color: #0000ff">void</span><span style="color: #000000"> resuedge(</span><span style="color: #0000ff">int</span><span style="color: #000000"> No)<br />{<br />    ed[ed[No].pre].next </span><span style="color: #000000">=</span><span style="color: #000000"> ed[ed[No].next].pre </span><span style="color: #000000">=</span><span style="color: #000000"> No;<br />}</span></div>需要删点的情况cMQ对单点表头处理卛_?br /><br />【具体题目?a title="PKU1815" >PKU1815</a><br />q题是求有向图的字典序最的最点割集问题Q方法是先求出最点q通度Q有x点q通度的求法见<a title="囄q通度问题的求? href="http://www.shnenglu.com/MatoNo1/archive/2011/04/05/143449.html">囄q通度问题的求?/a>Q,然后按编号递增序枚D每个点,若删去该点(其实是删d成的新图中该点i'到该炚w加点i''之间的边Q后囄最点q通度减小Q则应删去该点,否则不应删去该点。删dQl枚举下一个点Q直到求出点割集为止?br />注意Q本题只有删边,没有删点Q因此总表头可以不需要,直接从ed[0]开始作单点表头。此Ӟ关于是否IZ刚好反q来了:如果N是奇数就要空位,N是偶CIZQ不q这题里׃建出的网l流图中?*N0个结点,L偶数Q可以不,不过本沙茶还是管q个了)?br /><br />代码Q神犇不要鄙视)Q?br /> <div style="border-right: #cccccc 1px solid; padding-right: 5px; border-top: #cccccc 1px solid; padding-left: 4px; font-size: 13px; padding-bottom: 4px; border-left: #cccccc 1px solid; width: 98%; word-break: break-all; padding-top: 4px; border-bottom: #cccccc 1px solid; background-color: #eeeeee"><span style="color: #000000">#include </span><span style="color: #000000"><</span><span style="color: #000000">iostream</span><span style="color: #000000">></span><span style="color: #000000"><br />#include </span><span style="color: #000000"><</span><span style="color: #000000">stdio.h</span><span style="color: #000000">></span><span style="color: #000000"><br /></span><span style="color: #0000ff">using</span><span style="color: #000000"> </span><span style="color: #0000ff">namespace</span><span style="color: #000000"> std;<br /></span><span style="color: #0000ff">#define</span><span style="color: #000000"> re(i, n) for (int i=0; i<n; i++)</span><span style="color: #000000"><br /></span><span style="color: #0000ff">const</span><span style="color: #000000"> </span><span style="color: #0000ff">int</span><span style="color: #000000"> MAXN </span><span style="color: #000000">=</span><span style="color: #000000"> </span><span style="color: #000000">501</span><span style="color: #000000">, MAXM </span><span style="color: #000000">=</span><span style="color: #000000"> </span><span style="color: #000000">100000</span><span style="color: #000000">, INF </span><span style="color: #000000">=</span><span style="color: #000000"> </span><span style="color: #000000">~</span><span style="color: #000000">0U</span><span style="color: #000000"> </span><span style="color: #000000">>></span><span style="color: #000000"> </span><span style="color: #000000">2</span><span style="color: #000000">;<br /></span><span style="color: #0000ff">struct</span><span style="color: #000000"> edge {<br />    </span><span style="color: #0000ff">int</span><span style="color: #000000"> a, b, fs, f, pre, next;<br />} ed[MAXM </span><span style="color: #000000">+</span><span style="color: #000000"> MAXM];<br /></span><span style="color: #0000ff">int</span><span style="color: #000000"> n0, n, m </span><span style="color: #000000">=</span><span style="color: #000000"> </span><span style="color: #000000">0</span><span style="color: #000000">, s, t, start[MAXN], pr[MAXN], hs[MAXN], lev[MAXN], q[MAXN], now, flow, reslen </span><span style="color: #000000">=</span><span style="color: #000000"> </span><span style="color: #000000">0</span><span style="color: #000000">, res[MAXN];<br /></span><span style="color: #0000ff">bool</span><span style="color: #000000"> vst[MAXN];<br /></span><span style="color: #0000ff">void</span><span style="color: #000000"> init_d()<br />{<br />    re(i, n) {ed[i].a </span><span style="color: #000000">=</span><span style="color: #000000"> i; ed[i].b </span><span style="color: #000000">=</span><span style="color: #000000"> </span><span style="color: #000000">-</span><span style="color: #000000">1</span><span style="color: #000000">; ed[i].f </span><span style="color: #000000">=</span><span style="color: #000000"> </span><span style="color: #000000">0</span><span style="color: #000000">; ed[i].pre </span><span style="color: #000000">=</span><span style="color: #000000"> ed[i].next </span><span style="color: #000000">=</span><span style="color: #000000"> i;}<br />    </span><span style="color: #0000ff">if</span><span style="color: #000000"> (n </span><span style="color: #000000">%</span><span style="color: #000000"> </span><span style="color: #000000">2</span><span style="color: #000000">) m </span><span style="color: #000000">=</span><span style="color: #000000"> n </span><span style="color: #000000">+</span><span style="color: #000000"> </span><span style="color: #000000">1</span><span style="color: #000000">; </span><span style="color: #0000ff">else</span><span style="color: #000000"> m </span><span style="color: #000000">=</span><span style="color: #000000"> n;<br />}<br /></span><span style="color: #0000ff">void</span><span style="color: #000000"> add_edge(</span><span style="color: #0000ff">int</span><span style="color: #000000"> a, </span><span style="color: #0000ff">int</span><span style="color: #000000"> b, </span><span style="color: #0000ff">int</span><span style="color: #000000"> f)<br />{<br />    ed[m].a </span><span style="color: #000000">=</span><span style="color: #000000"> a; ed[m].b </span><span style="color: #000000">=</span><span style="color: #000000"> b; ed[m].fs </span><span style="color: #000000">=</span><span style="color: #000000"> ed[m].f </span><span style="color: #000000">=</span><span style="color: #000000"> f; ed[m].pre </span><span style="color: #000000">=</span><span style="color: #000000"> ed[a].pre; ed[m].next </span><span style="color: #000000">=</span><span style="color: #000000"> a; ed[a].pre </span><span style="color: #000000">=</span><span style="color: #000000"> m; ed[ed[m].pre].next </span><span style="color: #000000">=</span><span style="color: #000000"> m</span><span style="color: #000000">++</span><span style="color: #000000">;<br />    ed[m].a </span><span style="color: #000000">=</span><span style="color: #000000"> b; ed[m].b </span><span style="color: #000000">=</span><span style="color: #000000"> a; ed[m].fs </span><span style="color: #000000">=</span><span style="color: #000000"> ed[m].f </span><span style="color: #000000">=</span><span style="color: #000000"> </span><span style="color: #000000">0</span><span style="color: #000000">; ed[m].pre </span><span style="color: #000000">=</span><span style="color: #000000"> ed[b].pre; ed[m].next </span><span style="color: #000000">=</span><span style="color: #000000"> b; ed[b].pre </span><span style="color: #000000">=</span><span style="color: #000000"> m; ed[ed[m].pre].next </span><span style="color: #000000">=</span><span style="color: #000000"> m</span><span style="color: #000000">++</span><span style="color: #000000">;<br />}<br /></span><span style="color: #0000ff">void</span><span style="color: #000000"> init()<br />{<br />    </span><span style="color: #0000ff">int</span><span style="color: #000000"> x;<br />    scanf(</span><span style="color: #000000">"</span><span style="color: #000000">%d%d%d</span><span style="color: #000000">"</span><span style="color: #000000">, </span><span style="color: #000000">&</span><span style="color: #000000">n0, </span><span style="color: #000000">&</span><span style="color: #000000">s, </span><span style="color: #000000">&</span><span style="color: #000000">t);<br />    n </span><span style="color: #000000">=</span><span style="color: #000000"> n0 </span><span style="color: #000000"><<</span><span style="color: #000000"> </span><span style="color: #000000">1</span><span style="color: #000000">; s</span><span style="color: #000000">--</span><span style="color: #000000">; t </span><span style="color: #000000">+=</span><span style="color: #000000"> n0 </span><span style="color: #000000">-</span><span style="color: #000000"> </span><span style="color: #000000">1</span><span style="color: #000000">; init_d();<br />    re(i, n0) re(j, n0) {<br />        scanf(</span><span style="color: #000000">"</span><span style="color: #000000">%d</span><span style="color: #000000">"</span><span style="color: #000000">, </span><span style="color: #000000">&</span><span style="color: #000000">x);<br />        </span><span style="color: #0000ff">if</span><span style="color: #000000"> (i </span><span style="color: #000000">==</span><span style="color: #000000"> j) {<br />            </span><span style="color: #0000ff">if</span><span style="color: #000000"> (i </span><span style="color: #000000">==</span><span style="color: #000000"> s </span><span style="color: #000000">||</span><span style="color: #000000"> i </span><span style="color: #000000">==</span><span style="color: #000000"> t </span><span style="color: #000000">-</span><span style="color: #000000"> n0) add_edge(i, i </span><span style="color: #000000">+</span><span style="color: #000000"> n0, INF); </span><span style="color: #0000ff">else</span><span style="color: #000000"> add_edge(i, i </span><span style="color: #000000">+</span><span style="color: #000000"> n0, </span><span style="color: #000000">1</span><span style="color: #000000">);<br />        } </span><span style="color: #0000ff">else</span><span style="color: #000000"> </span><span style="color: #0000ff">if</span><span style="color: #000000"> (x) add_edge(i </span><span style="color: #000000">+</span><span style="color: #000000"> n0, j, INF);<br />    }<br />}<br /></span><span style="color: #0000ff">void</span><span style="color: #000000"> aug()<br />{<br />    </span><span style="color: #0000ff">int</span><span style="color: #000000"> z </span><span style="color: #000000">=</span><span style="color: #000000"> hs[t], i </span><span style="color: #000000">=</span><span style="color: #000000"> t, p; flow </span><span style="color: #000000">+=</span><span style="color: #000000"> z;<br />    </span><span style="color: #0000ff">while</span><span style="color: #000000"> (i </span><span style="color: #000000">!=</span><span style="color: #000000"> s) {<br />        hs[i] </span><span style="color: #000000">-=</span><span style="color: #000000"> z; p </span><span style="color: #000000">=</span><span style="color: #000000"> pr[i]; ed[p].f </span><span style="color: #000000">-=</span><span style="color: #000000"> z; ed[p </span><span style="color: #000000">^</span><span style="color: #000000"> </span><span style="color: #000000">1</span><span style="color: #000000">].f </span><span style="color: #000000">+=</span><span style="color: #000000"> z; i </span><span style="color: #000000">=</span><span style="color: #000000"> ed[p].a;<br />        </span><span style="color: #0000ff">if</span><span style="color: #000000"> (</span><span style="color: #000000">!</span><span style="color: #000000">ed[p].f) now </span><span style="color: #000000">=</span><span style="color: #000000"> i;<br />    }<br />}<br /></span><span style="color: #0000ff">bool</span><span style="color: #000000"> dfs()<br />{<br />    re(i, n) vst[i] </span><span style="color: #000000">=</span><span style="color: #000000"> </span><span style="color: #000000">0</span><span style="color: #000000">; vst[s] </span><span style="color: #000000">=</span><span style="color: #000000"> </span><span style="color: #000000">1</span><span style="color: #000000">; q[</span><span style="color: #000000">0</span><span style="color: #000000">] </span><span style="color: #000000">=</span><span style="color: #000000"> s; lev[s] </span><span style="color: #000000">=</span><span style="color: #000000"> </span><span style="color: #000000">0</span><span style="color: #000000">;<br />    </span><span style="color: #0000ff">int</span><span style="color: #000000"> i, j, f0;<br />    </span><span style="color: #0000ff">for</span><span style="color: #000000"> (</span><span style="color: #0000ff">int</span><span style="color: #000000"> front</span><span style="color: #000000">=</span><span style="color: #000000">0</span><span style="color: #000000">, rear</span><span style="color: #000000">=</span><span style="color: #000000">0</span><span style="color: #000000">; front</span><span style="color: #000000"><=</span><span style="color: #000000">rear; front</span><span style="color: #000000">++</span><span style="color: #000000">) {<br />        i </span><span style="color: #000000">=</span><span style="color: #000000"> q[front];<br />        </span><span style="color: #0000ff">for</span><span style="color: #000000"> (</span><span style="color: #0000ff">int</span><span style="color: #000000"> p</span><span style="color: #000000">=</span><span style="color: #000000">ed[i].next; p </span><span style="color: #000000">!=</span><span style="color: #000000"> i; p</span><span style="color: #000000">=</span><span style="color: #000000">ed[p].next) </span><span style="color: #0000ff">if</span><span style="color: #000000"> (ed[p].f) {<br />            j </span><span style="color: #000000">=</span><span style="color: #000000"> ed[p].b;<br />            </span><span style="color: #0000ff">if</span><span style="color: #000000"> (</span><span style="color: #000000">!</span><span style="color: #000000">vst[j]) {vst[j] </span><span style="color: #000000">=</span><span style="color: #000000"> </span><span style="color: #000000">1</span><span style="color: #000000">; q[</span><span style="color: #000000">++</span><span style="color: #000000">rear] </span><span style="color: #000000">=</span><span style="color: #000000"> j; lev[j] </span><span style="color: #000000">=</span><span style="color: #000000"> lev[i] </span><span style="color: #000000">+</span><span style="color: #000000"> </span><span style="color: #000000">1</span><span style="color: #000000">;}<br />        }<br />    }<br />    </span><span style="color: #0000ff">if</span><span style="color: #000000"> (</span><span style="color: #000000">!</span><span style="color: #000000">vst[t]) </span><span style="color: #0000ff">return</span><span style="color: #000000"> </span><span style="color: #000000">0</span><span style="color: #000000">;<br />    now </span><span style="color: #000000">=</span><span style="color: #000000"> s; re(i, n) {start[i] </span><span style="color: #000000">=</span><span style="color: #000000"> ed[i].next; vst[i] </span><span style="color: #000000">=</span><span style="color: #000000"> </span><span style="color: #000000">0</span><span style="color: #000000">;} hs[now] </span><span style="color: #000000">=</span><span style="color: #000000"> INF;<br />    </span><span style="color: #0000ff">bool</span><span style="color: #000000"> fd;<br />    </span><span style="color: #0000ff">while</span><span style="color: #000000"> (</span><span style="color: #000000">!</span><span style="color: #000000">vst[s]) {<br />        </span><span style="color: #0000ff">if</span><span style="color: #000000"> (now </span><span style="color: #000000">==</span><span style="color: #000000"> t) aug();<br />        fd </span><span style="color: #000000">=</span><span style="color: #000000"> </span><span style="color: #000000">0</span><span style="color: #000000">;<br />        </span><span style="color: #0000ff">for</span><span style="color: #000000"> (</span><span style="color: #0000ff">int</span><span style="color: #000000"> p</span><span style="color: #000000">=</span><span style="color: #000000">start[now]; p </span><span style="color: #000000">!=</span><span style="color: #000000"> now; p</span><span style="color: #000000">=</span><span style="color: #000000">ed[p].next) {<br />            j </span><span style="color: #000000">=</span><span style="color: #000000"> ed[p].b; f0 </span><span style="color: #000000">=</span><span style="color: #000000"> ed[p].f;<br />            </span><span style="color: #0000ff">if</span><span style="color: #000000"> (lev[now] </span><span style="color: #000000">+</span><span style="color: #000000"> </span><span style="color: #000000">1</span><span style="color: #000000"> </span><span style="color: #000000">==</span><span style="color: #000000"> lev[j] </span><span style="color: #000000">&&</span><span style="color: #000000"> </span><span style="color: #000000">!</span><span style="color: #000000">vst[j] </span><span style="color: #000000">&&</span><span style="color: #000000"> f0) {<br />                fd </span><span style="color: #000000">=</span><span style="color: #000000"> </span><span style="color: #000000">1</span><span style="color: #000000">; start[now] </span><span style="color: #000000">=</span><span style="color: #000000"> pr[j] </span><span style="color: #000000">=</span><span style="color: #000000"> p; hs[j] </span><span style="color: #000000">=</span><span style="color: #000000"> hs[now] </span><span style="color: #000000"><=</span><span style="color: #000000"> f0 </span><span style="color: #000000">?</span><span style="color: #000000"> hs[now] : f0; now </span><span style="color: #000000">=</span><span style="color: #000000"> j; </span><span style="color: #0000ff">break</span><span style="color: #000000">;<br />            }<br />        }<br />        </span><span style="color: #0000ff">if</span><span style="color: #000000"> (</span><span style="color: #000000">!</span><span style="color: #000000">fd) {<br />            vst[now] </span><span style="color: #000000">=</span><span style="color: #000000"> </span><span style="color: #000000">1</span><span style="color: #000000">;<br />            </span><span style="color: #0000ff">if</span><span style="color: #000000"> (now </span><span style="color: #000000">!=</span><span style="color: #000000"> s) now </span><span style="color: #000000">=</span><span style="color: #000000"> ed[pr[now]].a;<br />        }<br />    }<br />    </span><span style="color: #0000ff">return</span><span style="color: #000000"> </span><span style="color: #000000">1</span><span style="color: #000000">;<br />}<br /></span><span style="color: #0000ff">void</span><span style="color: #000000"> deledge(</span><span style="color: #0000ff">int</span><span style="color: #000000"> No)<br />{<br />    ed[ed[No].pre].next </span><span style="color: #000000">=</span><span style="color: #000000"> ed[No].next; ed[ed[No].next].pre </span><span style="color: #000000">=</span><span style="color: #000000"> ed[No].pre;<br />}<br /></span><span style="color: #0000ff">void</span><span style="color: #000000"> resuedge(</span><span style="color: #0000ff">int</span><span style="color: #000000"> No)<br />{<br />    ed[ed[No].pre].next </span><span style="color: #000000">=</span><span style="color: #000000"> ed[ed[No].next].pre </span><span style="color: #000000">=</span><span style="color: #000000"> No;<br />}<br /></span><span style="color: #0000ff">void</span><span style="color: #000000"> resu_all()<br />{<br />    re(i, n) </span><span style="color: #0000ff">for</span><span style="color: #000000"> (</span><span style="color: #0000ff">int</span><span style="color: #000000"> p</span><span style="color: #000000">=</span><span style="color: #000000">ed[i].next; p </span><span style="color: #000000">!=</span><span style="color: #000000"> i; p</span><span style="color: #000000">=</span><span style="color: #000000">ed[p].next) ed[p].f </span><span style="color: #000000">=</span><span style="color: #000000"> ed[p].fs;<br />}<br /></span><span style="color: #0000ff">void</span><span style="color: #000000"> solve()<br />{<br />    flow </span><span style="color: #000000">=</span><span style="color: #000000"> </span><span style="color: #000000">0</span><span style="color: #000000">; </span><span style="color: #0000ff">while</span><span style="color: #000000"> (dfs()) ; </span><span style="color: #0000ff">int</span><span style="color: #000000"> f_ </span><span style="color: #000000">=</span><span style="color: #000000"> flow;<br />    </span><span style="color: #0000ff">if</span><span style="color: #000000"> (</span><span style="color: #000000">!</span><span style="color: #000000">flow) {reslen </span><span style="color: #000000">=</span><span style="color: #000000"> </span><span style="color: #000000">-</span><span style="color: #000000">1</span><span style="color: #000000">; </span><span style="color: #0000ff">return</span><span style="color: #000000">;}<br />    re(i, m) </span><span style="color: #0000ff">if</span><span style="color: #000000"> (ed[i].a </span><span style="color: #000000">+</span><span style="color: #000000"> n0 </span><span style="color: #000000">==</span><span style="color: #000000"> ed[i].b </span><span style="color: #000000">&&</span><span style="color: #000000"> ed[i].a </span><span style="color: #000000">!=</span><span style="color: #000000"> s </span><span style="color: #000000">&&</span><span style="color: #000000"> ed[i].b </span><span style="color: #000000">!=</span><span style="color: #000000"> t) {<br />        deledge(i); deledge(i </span><span style="color: #000000">^</span><span style="color: #000000"> </span><span style="color: #000000">1</span><span style="color: #000000">); resu_all();<br />        flow </span><span style="color: #000000">=</span><span style="color: #000000"> </span><span style="color: #000000">0</span><span style="color: #000000">; </span><span style="color: #0000ff">while</span><span style="color: #000000"> (dfs()) ;<br />        </span><span style="color: #0000ff">if</span><span style="color: #000000"> (flow </span><span style="color: #000000"><</span><span style="color: #000000"> f_) {res[reslen</span><span style="color: #000000">++</span><span style="color: #000000">] </span><span style="color: #000000">=</span><span style="color: #000000"> ed[i].a </span><span style="color: #000000">+</span><span style="color: #000000"> </span><span style="color: #000000">1</span><span style="color: #000000">; f_</span><span style="color: #000000">--</span><span style="color: #000000">;} </span><span style="color: #0000ff">else</span><span style="color: #000000"> {resuedge(i </span><span style="color: #000000">^</span><span style="color: #000000"> </span><span style="color: #000000">1</span><span style="color: #000000">); resuedge(i);}<br />    }<br />}<br /></span><span style="color: #0000ff">void</span><span style="color: #000000"> pri()<br />{<br />    </span><span style="color: #0000ff">if</span><span style="color: #000000"> (reslen </span><span style="color: #000000">==</span><span style="color: #000000"> </span><span style="color: #000000">-</span><span style="color: #000000">1</span><span style="color: #000000">) puts(</span><span style="color: #000000">"</span><span style="color: #000000">0</span><span style="color: #000000">"</span><span style="color: #000000">); </span><span style="color: #0000ff">else</span><span style="color: #000000"> </span><span style="color: #0000ff">if</span><span style="color: #000000"> (reslen) {<br />        printf(</span><span style="color: #000000">"</span><span style="color: #000000">%d\n</span><span style="color: #000000">"</span><span style="color: #000000">, reslen);<br />        re(i, reslen </span><span style="color: #000000">-</span><span style="color: #000000"> </span><span style="color: #000000">1</span><span style="color: #000000">) printf(</span><span style="color: #000000">"</span><span style="color: #000000">%d </span><span style="color: #000000">"</span><span style="color: #000000">, res[i]); printf(</span><span style="color: #000000">"</span><span style="color: #000000">%d\n</span><span style="color: #000000">"</span><span style="color: #000000">, res[reslen </span><span style="color: #000000">-</span><span style="color: #000000"> </span><span style="color: #000000">1</span><span style="color: #000000">]);<br />    } </span><span style="color: #0000ff">else</span><span style="color: #000000"> puts(</span><span style="color: #000000">"</span><span style="color: #000000">NO ANSWER!</span><span style="color: #000000">"</span><span style="color: #000000">);<br />}<br /></span><span style="color: #0000ff">int</span><span style="color: #000000"> main()<br />{<br />    init();<br />    solve();<br />    pri();<br />    </span><span style="color: #0000ff">return</span><span style="color: #000000"> </span><span style="color: #000000">0</span><span style="color: #000000">;<br />}<br /></span></div><br /><img src ="http://www.shnenglu.com/MatoNo1/aggbug/145885.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.shnenglu.com/MatoNo1/" target="_blank">Mato_No1</a> 2011-05-07 14:12 <a href="http://www.shnenglu.com/MatoNo1/archive/2011/05/07/145885.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>用A*求图的单源单汇第K短\http://www.shnenglu.com/MatoNo1/archive/2011/05/01/145456.htmlMato_No1Mato_No1Sun, 01 May 2011 07:25:00 GMThttp://www.shnenglu.com/MatoNo1/archive/2011/05/01/145456.htmlhttp://www.shnenglu.com/MatoNo1/comments/145456.htmlhttp://www.shnenglu.com/MatoNo1/archive/2011/05/01/145456.html#Feedback0http://www.shnenglu.com/MatoNo1/comments/commentRss/145456.htmlhttp://www.shnenglu.com/MatoNo1/services/trackbacks/145456.htmll出一个图G和指定的源点s、汇点tQ求图中从点s到点t的第K短\?br>【具体题目?a title=PKU2449 >PKU2449Q注意:本题有一个猥琐之处:不允许空路径。也是当s{于t时要K值加1Q?br>【算法?br>本题有一U最朴素的办法:攚wDijkstraQ一开始\?s, 0)Q这里设路径(i, l)表示从s到i的一条长度ؓl的\径)入队。然后,每次取队中长度最短的路径Q该路径(i, l)出队Q可以证明,若这是终点ؓi的\径第xơ出队,该\径一定是图中从s到i的第x短\Q若x>K则该路径已无用,舍弃Q。然后从点i扩展Q将扩展到的路径全部入队。这L到终点ؓt的\径第Kơ出队即可?br>该算法容易实玎ͼ借助priority_queueQ,但时间复杂度可能辑ֈO(MK)Q需要优化?br>优化Q容易发现该法其实有A*的思想Q或者说Q该法其实是所有结点的Ch函数h()值均?的A*法。ؓ了优化此题,需要将h()值改大。显Ӟh(i)值可以设?span style="COLOR: red">从i到t的最短\径长?/strong>Q容易证明它是一致的Q,然后g(i)=目前l点代表的\径长度,f(i)=g(i)+h(i)Q然后A*卛_?br>
注意Q更改\径条数应该在出队时更改,而不能在入队时更改,因ؓ可能在该路径出队之前会有新的比它更短的\径入队?br>
代码QPKU2449Q:
#include <iostream>
#include 
<stdio.h>
#include 
<queue>
using namespace std;
#define re(i, n) for (int i=0; i<n; i++)
const int MAXN = 1500, MAXM = 150000, INF = ~0U >> 2;
struct edge {
    
int kk, len, next;
} ed[MAXM], ed2[MAXM];
int n, m, s, t, k_, hd[MAXN], tl[MAXN], hd2[MAXN], tl2[MAXN], h[MAXN], q[MAXN + 1], No[MAXN], res = -1;
bool vst[MAXN];
struct qnode {
    
int i, g;
};
typedef priority_queue 
<qnode, vector<qnode> > pq;
pq z;
bool operator< (qnode q1, qnode q2)
{
    
return q1.g + h[q1.i] > q2.g + h[q2.i];
}
void init()
{
    
int a0, b0, l0;
    scanf(
"%d%d"&n, &m);
    re(i, n) hd[i] 
= tl[i] = hd2[i] = tl2[i] = -1;
    re(i, m) {
        scanf(
"%d%d%d"&a0, &b0, &l0); a0--; b0--;
        ed[i].kk 
= b0; ed[i].len = l0; ed[i].next = -1;
        
if (hd[a0] == -1) hd[a0] = tl[a0] = i; else tl[a0] = ed[tl[a0]].next = i;
        ed2[i].kk 
= a0; ed2[i].len = l0; ed2[i].next = -1;
        
if (hd2[b0] == -1) hd2[b0] = tl2[b0] = i; else tl2[b0] = ed2[tl2[b0]].next = i;
    }
    scanf(
"%d%d%d"&s, &t, &k_); --s; --t; k_ += s == t;
}
void prepare()
{
    re(i, n) {h[i] 
= INF; vst[i] = 0;} h[t] = 0; vst[t] = 1; q[0= t;
    
int i, h0, j, h1;
    
for (int front=0, rear=0!(!front && rear == n || front == rear + 1); front == n ? front = 0 : front++) {
        i 
= q[front]; h0 = h[i];
        
for (int p=hd2[i]; p != -1; p=ed2[p].next) {
            j 
= ed2[p].kk; h1 = h0 + ed2[p].len;
            
if (h1 < h[j]) {
                h[j] 
= h1;
                
if (!vst[j]) {vst[j] = 1if (rear == n) q[rear = 0= j; else q[++rear] = j;}
            }
        }
        vst[i] 
= 0;
    }
}
void solve()
{
    qnode q0; q0.i 
= s; q0.g = 0; z.push(q0);
    re(i, n) No[i] 
= 0;
    
int i, d0, j, d1;
    
while (!z.empty()) {
        i 
= z.top().i; d0 = z.top().g; z.pop();
        
if (No[i] >= k_) continue;
        No[i]
++;
        
if (i == t && No[i] == k_) {res = d0; break;}
        
for (int p=hd[i]; p != -1; p=ed[p].next) {
            j 
= ed[p].kk; d1 = d0 + ed[p].len;
            q0.i 
= j; q0.g = d1; z.push(q0);
        }
    }
}
void pri()
{
    printf(
"%d\n", res);
}
int main()
{
    init();
    prepare();
    solve();
    pri();
    
return 0;
}


Mato_No1 2011-05-01 15:25 发表评论
]]>
动态区间最大子序和问题及有x?/title><link>http://www.shnenglu.com/MatoNo1/archive/2011/04/24/144901.html</link><dc:creator>Mato_No1</dc:creator><author>Mato_No1</author><pubDate>Sun, 24 Apr 2011 07:50:00 GMT</pubDate><guid>http://www.shnenglu.com/MatoNo1/archive/2011/04/24/144901.html</guid><wfw:comment>http://www.shnenglu.com/MatoNo1/comments/144901.html</wfw:comment><comments>http://www.shnenglu.com/MatoNo1/archive/2011/04/24/144901.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.shnenglu.com/MatoNo1/comments/commentRss/144901.html</wfw:commentRss><trackback:ping>http://www.shnenglu.com/MatoNo1/services/trackbacks/144901.html</trackback:ping><description><![CDATA[     摘要: 动态区间最大子序和问题【问题描q】给Z个序列A[0..N-1]和M个操作,每个操作都是以下三种之一Q①Q查询区间最大子序和操作格式Q? l r表示Q查询A[l..r]内的最大子序和Q就是A[l..r]内的和最大的q箋子序列的和)Q?<=l<=r<NQ②Q修改单个值操作格式:2 i x表示Q将A[i]的值改为xQ?<=i<NQ③Q修ҎD值操作格式:3 l ...  <a href='http://www.shnenglu.com/MatoNo1/archive/2011/04/24/144901.html'>阅读全文</a><img src ="http://www.shnenglu.com/MatoNo1/aggbug/144901.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.shnenglu.com/MatoNo1/" target="_blank">Mato_No1</a> 2011-04-24 15:50 <a href="http://www.shnenglu.com/MatoNo1/archive/2011/04/24/144901.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>环Ş串的最优断炚w?/title><link>http://www.shnenglu.com/MatoNo1/archive/2011/04/23/144852.html</link><dc:creator>Mato_No1</dc:creator><author>Mato_No1</author><pubDate>Sat, 23 Apr 2011 08:09:00 GMT</pubDate><guid>http://www.shnenglu.com/MatoNo1/archive/2011/04/23/144852.html</guid><wfw:comment>http://www.shnenglu.com/MatoNo1/comments/144852.html</wfw:comment><comments>http://www.shnenglu.com/MatoNo1/archive/2011/04/23/144852.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.shnenglu.com/MatoNo1/comments/commentRss/144852.html</wfw:commentRss><trackback:ping>http://www.shnenglu.com/MatoNo1/services/trackbacks/144852.html</trackback:ping><description><![CDATA[【问题描q?br>l出一个环形的字符串SQ长度ؓNQ现在要扑ֈ一个断开点,使得从这里断开后的字符串字典序最。或者说Q对于长度ؓN的字W串S[0..N-1]Q找C个位|iQ得字W串S' = S[i..N-1] + S[0..i-1]的字典序最。若存在多个q样的最优断点,则取最左边(i最?的那个?br>【Sample Input?br>amandamanda<br>【Sample Output?br>10<br>Q从W?0位断开后得到的字符?aamandamand"的字典序?1个断开位置中最的Q?br><br>【分析?br>首先这个环形串拆开Q只需S[0..N-1]的后面再接上S[0..N-2]卛_Q如对于样例Q可构造字W串T = "amandamandaamandamand"Q,则T的Q意一个长度ؓN的子串T[i..i-N+1]是S从第i位断开得到的字W串。此旉题就变成了:<span style="COLOR: red"><strong>l出一个长度ؓ(2N-1)的字W串Q求出其所有长度ؓN的子串中字典序最的</strong></span>?br><br>设F[x]?span style="COLOR: red"><strong>T中所有v始位于N的长度ؓx的子串中字典序最的子串的v始位Q若有多个则取最左边的)</strong></span>Q如对于T="abaabaaababaabaaa"Q有F[0]=F[1]=0QF[2]=2QF[3]=F[4]=5……本题的目的就是求出F[N]的倹{一开始已知的只有F[0]=0Q长度ؓ0的字W串都是IZQ字典序都是最的Q取最左边的第0位)?br><br>可以发现QF数组有很多重要的性质Q?br><span style="COLOR: #ff0000"><strong>性质1 F[0..N]数组是单调递增的?/strong></span><br>证明Q用反证法。设存在一个值x(0<=x<N)使得F[x]>F[x+1]则根据定义,有T[F[x+1]..F[x+1]+x]<=T[F[x]..F[x]+x]Q这里一定不会越界,即F[x]+x的g定不大于(2N-1)Q因为x<NQ又Ҏ得F[x]<NQ故F[x]+x<2NQ,q样Q必有T[F[x+1]..F[x+1]+x-1]<=T[F[x]..F[x]+x-1]。然而根据F[x]的定义又可以得到T[F[x+1]..F[x+1]+x-1]>T[F[x]..F[x]+x-1]Q否则F[x]的值就应该{于F[x+1]的gQ,矛盾Q故在F[0..N]中不可能存在MF[x]>F[x+1]的情况,也即F[0..N]数组是单调递增的(以下F[0..N]数组UCؓF数组Q?br><span style="COLOR: #ff0000"><strong>性质2 对于L值x(0<=x<N)Q必然满F[x+1]=F[x]或F[x+1]>F[x]+x?/strong></span><br>证明Q因为前面已l证明了F数组是单调递增的,q里只需证明对于Lx(0<=x<N)Q不存F[x]<F[x+1]<=F[x]+x的情况即可?br>q里同样用反证法。设存在一个值x(0<=x<N)使得F[x]<F[x+1]<=F[x]+x。则Ҏ定义有T[F[x+1]..F[x+1]+x]<T[F[x]..F[x]+x]且T[F[x]..F[x]+x-1]<=T[F[x+1]..F[x+1]+x-1]Q这样必有T[F[x]..F[x]+x-1]=T[F[x+1]..F[x+1]+x-1]且T[F[x+1]+x]<T[F[x]+x]。设D=F[x+1]-F[x]Q则T[F[x]]=T[F[x]+D]Q因为D<=xQ可得T[F[x]+D]=T[F[x]+2D]Q即T[F[x]]=T[F[x]+2D]。这PT[F[x]..F[x]+x-D-1]=T[F[x]+2D..F[x]+x+D-1]Q又因ؓT[F[x]+x-D]=T[F[x]+x]Q而T[F[x+1]+x]Q即T[F[x]+x+D]]Q?lt;T[F[x]+x]Q这PT[F[x]+x+D]<T[F[x]+x-D]Q也是QT[F[x]+2D..F[x]+x+D]<T[F[x]..F[x]+x-D]Q这样可以得出,?F[x]+2D)位开始的L长度不小?x-D)的子Ԍ其字典序都小于从F[x]位开始的同样长度的子Ԍ׃F[x]<F[x+1]<=F[x]+xQD=F[x+1]-F[x]Q所以有1<=D<=xQ这PF[x]的值就应该?F[x]+2D)了,q显然不可能。所以,一开始假讄q种情况是不可能存在的,卛_于Q意值xQ?<=x<NQ,必然满F[x+1]=F[x]或F[x+1]>F[x]+x?br><br>ҎF数组的以上两个性质可以设计出本题的法Q?br>讄前已l求ZF[0..x-1]的|且F[x-1]=i。首先将T[0..i-1]全部删去Q因为F数组是单调递增的,F[x]的g定不于iQ,然后对T自n作扩展KMPQ就是以T为模板串QT为子串的扩展KMPQ相当于光处理部分Q,一开始先F[x]|ؓiQ设Wj位的匚w长度为next[j]Q若next[j]=x-1且T[j+x-1]<T[i+x-1]Q则F[x]的值改为jQ这h描一遍,xZF[x]的倹{若扫描q程中未出现Mnext[j]=x-1Q则设所有next[j]g于x的最next[j]gؓyQ则可以直接得到F[x..y-1]的值均{于F[x-1]。就q样直到求出F[N]的gؓ止?br><br>旉复杂度:O(N<span style="FONT-FAMILY: symbol">Ö</span>N)Q可以根据性质2得到? <img src ="http://www.shnenglu.com/MatoNo1/aggbug/144852.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.shnenglu.com/MatoNo1/" target="_blank">Mato_No1</a> 2011-04-23 16:09 <a href="http://www.shnenglu.com/MatoNo1/archive/2011/04/23/144852.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>RMQ问题http://www.shnenglu.com/MatoNo1/archive/2011/03/26/142289.htmlMato_No1Mato_No1Sat, 26 Mar 2011 02:13:00 GMThttp://www.shnenglu.com/MatoNo1/archive/2011/03/26/142289.htmlhttp://www.shnenglu.com/MatoNo1/comments/142289.htmlhttp://www.shnenglu.com/MatoNo1/archive/2011/03/26/142289.html#Feedback1http://www.shnenglu.com/MatoNo1/comments/commentRss/142289.htmlhttp://www.shnenglu.com/MatoNo1/services/trackbacks/142289.html
【离URMQ问题?br>题意Q对于一个序列A[1..N]Q共有Mơ提问,每次都是问A[l..r]Q?<=l<=r<=N)中的最|求出每次提问的答案?br>
Q?Q纯暴力枚DQO(NM)Q?br>Q?Q树状数l:O(M(logN)^2)【见树状数组解决ȝRMQ问题?br>Q?QST法QO(MlogN)……
ST法是基于分块DP的?br>设F[i][j]为A[i..(i+2^j-1)]Q共2^j个元素)中的最|前提是不能越界,即i+2^j-1 <= NQ,昄F可以通过DP的方式得刎ͼ
F[i][j] = min||max{F[i][j-1], F[i+2^(j-1)][j-1]}
边界QF[i][0]=A[i]?br>DP求F的值的旉复杂度ؓO(NlogN)Q一共只有NlogN个F值有意义Q;

然后Q对于求A[l..r]中的最|只要A[l..r]拆成若干q箋的段Q得每D늚长度都是2的整数次q就行了Q比如A[3..28]可以拆成A[3..18]、A[19..26]、A[27..28]三段Q长度分别是16Q?^4Q?Q?^3Q?Q?^1Q,所以min||max{A[3..28]} = min||max{F[3][4], F[19][3], F[27][1]}?br>关键是怎么拆?ҎQ求?r-l+1)Q即A[l..r]的长度)的二q制形式Q然后从高位C位依ơ遍历,如果扑ֈ1位就加上目前的位对应的幂Q如(28-3+1)=(11010)2Q所以依ơ找到F[3][4]、F[3+2^4][3]、F[3+2^4+2^3][1]。注意此旉要预先设一个数lBQB[2^i]=iQ以方便扑ֈ某个取出的幂对应的指数?br>昄Q最多只有logND,所以一ơ提问的旉复杂度ؓO(logN)?br>
其实q有一U方法,是先求出log(r-l+1)的|下取_Q设为xQ然后F[l][x]和F[r-2^x+1][x]中的较大/较小值就是A[l..r]中的最倹{这P一ơ提问的旉复杂度就降到了O(1)。问题是Q系llog函数灰常慢,也许一ơlog函数值的旉已经过了logNQ这h然得不偿失。所以仍然推荐上面的Ҏ?br>
【核心代码(以求最gؓ例,最大值类|?br>分段法:
int MIN(int l0, int r0)
{
    
int min = INF, h = l0, d0, b0;
    
for (int d = r0 - l0 + 1; d; d -= d0) {
        d0 
= d & -d; b0 = B[d0];
        
if (F[h][b0] < min) min = F[h][b0];
        h 
+= d0;
    }
    
return min;
}
求log值法Q?br>
int MIN(int l0, int r0)
{
    
int v = (int)floor(log2(r0 - l0 + 1.0)), s1 = F[l0][v], s2 = F[r0 - (1 << v) + 1][v];
    
return s1 <= s2 ? s1 : s2;
}
求F数组值的预处理代码(注意Q如果采用求log值的Ҏ׃需要B数组了)Q?br>
void prepare()
{
    re(i, n) F[i][
0= a[i];
    
int x;
    re2(j, 
1, MAXS) {
        
if ((1 << j) <= n) B[1 << j] = j;
        x 
= n - (1 << j) + 1;
        re(i, x) F[i][j] 
= min(F[i][j - 1], F[i + (1 << j - 1)][j - 1]);
    }
}

【后l效率测试,发现当N=M=100000的随机数据中Q两U方法都可以?.4s以内得出正确l果Q其中log值法比分D|略慢0.01s左右Q相差不大,但考虑?#8220;量用数学函?#8221;的原则,仍推荐分D|?br>


Mato_No1 2011-03-26 10:13 发表评论
]]>
ȾþֻоƷ| 999þþѹƷ| ۺϾþþ| ҹѸþӰԺ| ˾ҹվھƷþþþþþþ | þ޾Ʒۿ| ɫۺϾþĻ| ݺݺɫۺϾþð| þþþѿӰƬ| þһ| þоƷ| ھƷþþþӰԺ޹²| 뾫ƷþɪӰ| þþþþþþþþþþþ| þþþһ| þþƷþý| þĻ| þˬƬţţ| ھƷþۺ88| Ʒþˬ| ޾ƷҾþþþþ| þþƷУСŮ| AVպƷþþþ| 91ƷۺϾþ| ĻۺϾþ| þ޹Ʒ| Ʒþþ21p | www.þþƷ| þþþӰԺ| պݺݾþ͵͵ɫۺ96 | ŷ츾BBBþþ| þùӾƷŮ| 99þ99þþƷƬ| ҹƷþþĸ| ޵һƷƷþ| 97þ㽶߿ۿ| þ| þw5www| ޹˾ƷŮ˾þþ | ˹ھƷþþþӰԺ| Ʒþþþһ|