??xml version="1.0" encoding="utf-8" standalone="yes"?>久久久精品免费国产四虎,久久婷婷五月综合色奶水99啪,97久久天天综合色天天综合色hdhttp://www.shnenglu.com/MatoNo1/archive/2012/11/25/195647.htmlMato_No1Mato_No1Sun, 25 Nov 2012 06:54:00 GMThttp://www.shnenglu.com/MatoNo1/archive/2012/11/25/195647.htmlhttp://www.shnenglu.com/MatoNo1/comments/195647.htmlhttp://www.shnenglu.com/MatoNo1/archive/2012/11/25/195647.html#Feedback0http://www.shnenglu.com/MatoNo1/comments/commentRss/195647.htmlhttp://www.shnenglu.com/MatoNo1/services/trackbacks/195647.html原题地址
本沙茶去q曾l用双线D|的方法捉了这题(详见q里Q,最q重新审视这题发玎ͼ借助q树,可以得到更简单的Ҏ?br />
题目大意Q?br />有一个长度ؓN的内存条Q每个位|的状态有占用和不占用两种Q有4U操作:
Q?QResetQ清I所有内存(卛_所有位|的状态改Z占用Q删除所有内存块Q;
Q?QNew xQ申请一个新的内存块Q即扑ֈ一个长度ؓx的连l不占用位置区间Q将它们标记为占用,若有多个q样的区_取最左边的,若木有输出Reject NewQ?br />Q?QFree xQ在已申L内存块中Q找到包含位|x的ƈ释放Q将该内存块删除Q同时其占用的所有位|改Z占用Q,若木有内存块包含位置xQ则输出Reject FreeQ?br />Q?QGet xQ找出已甌的内存块中,左vWx个,q输出其左端点;若已甌的内存块数目不x个,则输出Reject Get?br />
可以发现Q每个已l申L内存块尽代表一D区_但仍然是独立的单位,因此Q可以把内存块当成结点,用^衡树l护Q关键字为内存块的左端点位置Q,New操作中内存块的插入与Free操作中内存块的删除均在此q树内q行QReset操作只需要将整棵树销毁即可?br />问题是,在New操作中,需要找C个长度ؓx的连l不占用区间Q而连l的不占用区间ƈ不是独立的单位,因此需要用线D|l护。在U段树中Q需要维?lt;1>l点区间内最长连l不占用块的长度Q?lt;2>l点区间左端、右端连l不占用块的长度Q否则无法维?lt;1>Q;同时Q由于在New操作中需要区间整体改占用QFree操作中又需要区间整体改不占用,所以应当支持整体改值的标记Q对于Reset操作Q只需要全部位|改不占用即可(不能重新建树Q!Q;

q样Q利用一^衡树加一늺D|Q就可以得到一个很单的Ҏ了(代码量是双^衡树或双U段树的一半左叻IQ?br />
q题的启C是Q在解决数据l构l计c题的时候,到底选用什么样的数据结构,是有讲究的,因ؓ它将直接影响到编E复杂度。一般来_U段树比q树好写,但是Ҏ题而言Q双U段树反而不如^衡树加线D|好写Q这是因为对于内存块使用q树维护比使用U段树维护更好。在以后做这U题的时候,要多想一下,扑ֈ便方法?br />

Mato_No1 2012-11-25 14:54 发表评论
]]>
数据l构复习题汇总(不断更新中)http://www.shnenglu.com/MatoNo1/archive/2011/07/23/151685.htmlMato_No1Mato_No1Fri, 22 Jul 2011 18:24:00 GMThttp://www.shnenglu.com/MatoNo1/archive/2011/07/23/151685.htmlhttp://www.shnenglu.com/MatoNo1/comments/151685.htmlhttp://www.shnenglu.com/MatoNo1/archive/2011/07/23/151685.html#Feedback0http://www.shnenglu.com/MatoNo1/comments/commentRss/151685.htmlhttp://www.shnenglu.com/MatoNo1/services/trackbacks/151685.htmlq里了囧Q第11)
可以发现本题是求一个比率rateQ得第i个hQ如果用的话Q工资ؓrate*QiQƈ且还要满以下两个限制条Ӟ
Q?Q每人的最低工资限ӞWi个h如果用的话,有rate*Qi>=SiQ即rate>=Si/QiQ?br />Q?Qd销限制Qrate*所有用的h的Qg?lt;=WQ即所有用的h的Qg?lt;=W/rate?br />q样Q可以先所有h按照(S/Q)的值递增排序Q然后枚N要用的最后一个hQ排序后的,也就是S/Q值最大的那个人)Q设为iQ则总花Ҏ省的做法昄是取rate=Si/Qi。然后根据(2Q式得出“所有用的h的Qg?#8221;的最大值W0=W/rateQ其中,Wi个h是必要用的Q故W0值先减去QiQ若W0<QiQ则Wi个h不可使用Q,剩下的问题就变成了在W?~(i-1)个h中(排序后的Q选取一些hQ得他们的Qg和不大于W0Qƈ且选取的h可能多。显然这可以用贪心来实现Q即选取Q值最的若干个h。接下来Q由于题目中N<=500000Q说明需要用数据l构来优化,可是Q的上限只?0000且Q为正整数Q因此,U段树是最好的选择。徏立一表C[1, 20000]的线D|Q每个结点存放两个额外的|sz和sumQ分别表CQg于该l点代表的区间内的h的L以及q些人的Q值d。然后,需要解决上q子问题Ӟ从根l点开始考察l点的sz|不断往下找卛_Q这有点像^衡树的找WK的操作Q?br />L间复杂度QO(N * (log20000 + logN))Q还有排序的旉Q?br />代码

??a title="RQNOJ469" >RQNOJ469
先按照Q意一U属性(q里为AQ递增排序Q然后枚丑րiQ排序后W?位~Wi位的全部lAQ看A属性,它们中A属性最大的一定是iQ,排序后第(i+1)位及以后的,看其B、C两种属性的大小Q若B属性更就看B属性,若C属性更就看C属性,然后得出两种属性的最大值即可。因此可以得C面的法Q先排序Q然后将所有的毛的B或C属性(哪种更小q哪种Q插入^衡树Q这里需要两^衡树Q一存放B属性的|一存放C属性的|Q然后递增枚DiQ注意i=0的情况不要漏掉)Q将Wi位的B或C属性在q树中删除Q然后找Z^衡树中的最大值即可?br />但是需要注意一U特D情况:所有的毛都看同一个属性,此时按照上面的算法可能求不出最优解Q比如:
10 6 5
10 2 8
此时Q第1个C属性更,W?个B属性更,若第1个看C属性,W?个看B属性,则d?+2=7Q而如果两个都看B属性则d?。此时就需要特判(预先求出三种属性中的最大|Q然后再用上面的法求解Q就能保证求出最优解了?br />代码

??a title="PKU2985" >PKU2985
q查?q树基本操作,水题Q不解释?br />代码

?】HNOI2011 括号匚wBracketsQ目前可以看q个帖子Q?br />Splay Treel护序列问题。对于一D|号序列A[1..len]Q定义优先P[0..len]如下Q?br />P[0]=0
P[i]=P[i-1]+1Qi>0且A[i]为左括号Q?br />P[i]=P[i-1]-1Qi>0且A[i]为右括号Q?br />然后QSplay Tree的每个结炚w要记录一个Z值和M|分别表示该结点代表的括号序列中最后一个元素的优先U和优先U最的元素的优先。则可以证明Q这D|号序列调整至q臛_需要改变的括号数目?-M+K+1) / 2Q其中K=Z+((-M+1)/2)*2Q注意这里的/是整除)Q此外由于有swap和invert两个操作Q因此需要记录RM、TM、RTM|分别表示该括号序列执行swap操作后的序列的M倹{执行invert操作后的序列的M|以及同时执行swap和invert操作后序列的M倹{?br />不过Q本题需要严重注意的是:虽然replace操作的标讎ͼ代码中的mk0Q会覆盖掉swapQ代码中的mk1Q和invertQ代码中的mk2Q操作的标记Q但是在下放标记的时候,需要对三种标记逐一判断Qmk0和mk1、mk2q不是不能共存的Q因为有可能先打上mk0标记后再打上mk1或mk2标记?/strong>
本题虽然是静态的Q但仍然不能使用U段树,因ؓU段树无法支持整体翻转(revQ操作?br />代码


Mato_No1 2011-07-23 02:24 发表评论
]]>
PKU3017http://www.shnenglu.com/MatoNo1/archive/2011/07/08/150454.htmlMato_No1Mato_No1Fri, 08 Jul 2011 04:40:00 GMThttp://www.shnenglu.com/MatoNo1/archive/2011/07/08/150454.htmlhttp://www.shnenglu.com/MatoNo1/comments/150454.htmlhttp://www.shnenglu.com/MatoNo1/archive/2011/07/08/150454.html#Feedback1http://www.shnenglu.com/MatoNo1/comments/commentRss/150454.htmlhttp://www.shnenglu.com/MatoNo1/services/trackbacks/150454.html【原题见q里?br />
本沙茶见q的最猥琐的DP题啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊?#8230;…

设F[i]为将A[1..i]拆分成若q段的最大值最和Q则?br />F[i]=min{F[j] + max[j+1, i]}QB[i]<=j<iQ,其中max[j+1, i]表示A[j+1..i]中的最大|B[i]表示从i向左最q可以g伸到哪里Q也是满SUM[x..i]<=m的最的x|。B数组可以通过预处理在O(N)旉内得到?br />边界QF[0]=0?br />
下面是优化过E。JZP犇的论文里面已l够详细了。这里只是简要说明一下?br />首先Ҏ证明QF是单调递增的?br />然后一个很关键的定理是Q?strong style="color: red">若F[i]的最优决{ؓjQ则有A[j]>∀A[k]Qj<k<=iQ?/strong>
证明Q用反证法。若A[j+1..i]中存在不于A[j]的|则可得max[j..i]=max[j+1..i]Q又因ؓF单调递增Q所以F[j-1]+max[j..i]<=F[j]+max[j+1.i]Q即决策(j-1)一定不比决{j差,也就是决{j不可能成为最优决{?br />q样Q可以维护一个下标严格递增、Ag格递减的队列QQ即对于队列中的L两个元素Q[i]和Q[j]Q若i<jQ则Q[i].pos<Q[j].pos且A[Q[i].pos]>A[Q[j].pos]Q具体实现时pos可省略)。则可能成ؓ最优决{的决策要么是在q个队列Q里,要么是B[i]。对于队列中的某个决{Q[x]Q该决策导出的gؓF[Q[x]]+A[Q[x + 1]]Q很Ҏ证明max[Q[x]+1..i]=A[Q[x + 1]]Q,扑ֈq些导出的g的最值即可(注意Q队օ素没有导出|。对于决{B[i]Q只需要在预处理的时候同时得到MAX[i]=max[B[i]+1..i]卛_Q也可以在O(N)旉内得刎ͼQ决{B[i]导出的gؓF[B[i]]+MAX[i]?br />在删除队首过时元素的时候,需要把导出g删除Q删除队օ素也一P插入的时候,若插入前队列不ؓI,则需要插入一个导出倹{也是Q需要一个支持在Ҏ旉内进行插入、删除Q意结炏V找最值等操作Q显然用q树最好?br />
注意事项Q?br />Q?Q不是在队首删除还是在队尾删除Q若删除的是队列中的最后一个元素,则不需要在q树中删除导出|
Q?Q插入时Q若插入前队列ؓI,则不需要在q树中插入导出|
Q?Q在计算F[i]Ӟ应先决{i压入?br />
代码Q?
#include <iostream>
#include 
<stdio.h>
using namespace std;
#define re1(i, n) for (int i=1; i<=n; i++)
const int MAXN = 100001;
struct node {
    
int l, r, p, sz0, sz, mul;
    
long long v;
} T[MAXN];
const long long INF = ~0Ull >> 2;
int n, N = 0, a[MAXN], b[MAXN], MAX[MAXN], Q[MAXN], front = 0, rear = -1, root = 0;
long long m, F[MAXN], res = 0;
void init()
{
    cin 
>> n >> m;
    re1(i, n) scanf(
"%d"&a[i]); a[0= ~0U >> 2;
}
void prepare()
{
    re1(i, n) 
if (a[i] > m) {res = -1return;}
    
int x = 1;
    
long long sum = 0;
    re1(i, n) {
        
for (sum+=a[i]; sum>m; sum-=a[x++]) ;
        b[i] 
= x - 1;
    }
    re1(i, n) {
        
for (; front<=rear && Q[front]<=b[i]; front++) ;
        
for (; front<=rear && a[Q[rear]]<=a[i]; rear--) ;
        Q[
++rear] = i; MAX[i] = a[Q[front]];
    }
}
void vst(int x)
{
    
if (x) {
        cout 
<< T[x].v << ' ';
        vst(T[x].l); vst(T[x].r);
    }
}
void slc(int _p, int _c)
{
    T[_p].l 
= _c; T[_c].p = _p;
}
void src(int _p, int _c)
{
    T[_p].r 
= _c; T[_c].p = _p;
}
void upd(int x)
{
    T[x].sz0 
= T[T[x].l].sz0 + T[T[x].r].sz0 + T[x].mul;
    T[x].sz 
= T[T[x].l].sz + T[T[x].r].sz + 1;
}
void lrot(int x)
{
    
int y = T[x].p;
    
if (y == root) T[root = x].p = 0else {int p = T[y].p; if (y == T[p].l) slc(p, x); else src(p, x);}
    src(y, T[x].l); slc(x, y); T[x].sz0 
= T[y].sz0; T[x].sz = T[y].sz; upd(y);
}
void rrot(int x)
{
    
int y = T[x].p;
    
if (y == root) T[root = x].p = 0else {int p = T[y].p; if (y == T[p].l) slc(p, x); else src(p, x);}
    slc(y, T[x].r); src(x, y); T[x].sz0 
= T[y].sz0; T[x].sz = T[y].sz; upd(y);
}
void maintain(int x, bool ff)
{
    
int z;
    
if (ff) {
        
if (T[T[T[x].r].r].sz > T[T[x].l].sz) {z = T[x].r; lrot(z);}
        
else if (T[T[T[x].r].l].sz > T[T[x].l].sz) {z = T[T[x].r].l; rrot(z); lrot(z);} else return;
    } 
else {
        
if (T[T[T[x].l].l].sz > T[T[x].r].sz) {z = T[x].l; rrot(z);}
        
else if (T[T[T[x].l].r].sz > T[T[x].r].sz) {z = T[T[x].l].r; lrot(z); rrot(z);} else return;
    }
    maintain(T[z].l, 
0); maintain(T[z].r, 1); maintain(z, 0); maintain(z, 1);
}
int find(long long _v)
{
    
int i = root;
    
long long v0;
    
while (i) {
        v0 
= T[i].v;
        
if (_v == v0) return i; else if (_v < v0) i = T[i].l; else i = T[i].r;
    }
    
return 0;
}
int Find_Kth(int K)
{
    
int i = root, s0, m0;
    
while (1) {
        s0 
= T[T[i].l].sz0; m0 = T[i].mul;
        
if (K <= s0) i = T[i].l; else if (K <= s0 + m0) return i; else {K -= s0 + m0; i = T[i].r;}
    }
}
void ins(long long _v)
{
    
if (!root) {
        T[
++N].v = _v; T[N].l = T[N].r = T[N].p = 0; T[N].sz0 = T[N].sz = T[N].mul = 1; root = N;
    } 
else {
        
int i = root, j;
        
long long v0;
        
while (1) {
            T[i].sz0
++; v0 = T[i].v;
            
if (_v == v0) {T[i].mul++return;} else if (_v < v0) j = T[i].l; else j = T[i].r;
            
if (j) i = j; else break;
        }
        T[
++N].v = _v; T[N].l = T[N].r = 0; T[N].sz0 = T[N].sz = T[N].mul = 1if (_v < v0) slc(i, N); else src(i, N);
        
while (i) {T[i].sz++; maintain(i, _v > T[i].v); i = T[i].p;}
    }
}
void del(int x)
{
    
if (T[x].mul > 1) {
        T[x].mul
--while (x) {T[x].sz0--; x = T[x].p;}
    } 
else {
        
int l = T[x].l, r = T[x].r, p;
        
if (l && r) {
            
int y; while (y = T[l].r) l = y;
            T[x].v 
= T[l].v; T[x].mul = T[l].mul; p = T[l].p;
            
if (l == T[p].l) slc(p, T[l].l); else src(p, T[l].l);
            
while (p) {upd(p); p = T[p].p;}
        } 
else {
            
if (x == root) T[root = l + r].p = 0else {p = T[x].p; if (x == T[p].l) slc(p, l + r); else src(p, l + r); while(p) {upd(p); p = T[p].p;}}
        }
    }
}
long long h(int x)
{
    
return F[Q[x]] + a[Q[x + 1]];
}
void solve()
{
    F[
0= 0; front = 0; rear = 0; Q[0= 0;
    re1(i, n) {
        
for (; front<=rear && Q[front]<b[i];) {if (front < rear) del(find(h(front))); front++;}
        
for (; front<=rear && a[Q[rear]]<=a[i];) {if (front < rear) del(find(h(rear - 1))); rear--;}
        Q[
++rear] = i; if (front < rear) ins(h(rear - 1));
        
if (root) F[i] = T[Find_Kth(1)].v; else F[i] = INF;
        
if (F[b[i]] + MAX[i] < F[i]) F[i] = F[b[i]] + MAX[i];
    }
    res 
= F[n];
}
void pri()
{
    cout 
<< res << endl;
}
int main()
{
    init();
    prepare();
    
if (!res) solve();
    pri();
    
return 0;
}



Mato_No1 2011-07-08 12:40 发表评论
]]>
U段树套q?可修改的区间WK问?/title><link>http://www.shnenglu.com/MatoNo1/archive/2011/06/27/149605.html</link><dc:creator>Mato_No1</dc:creator><author>Mato_No1</author><pubDate>Mon, 27 Jun 2011 13:53:00 GMT</pubDate><guid>http://www.shnenglu.com/MatoNo1/archive/2011/06/27/149605.html</guid><wfw:comment>http://www.shnenglu.com/MatoNo1/comments/149605.html</wfw:comment><comments>http://www.shnenglu.com/MatoNo1/archive/2011/06/27/149605.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.shnenglu.com/MatoNo1/comments/commentRss/149605.html</wfw:commentRss><trackback:ping>http://www.shnenglu.com/MatoNo1/services/trackbacks/149605.html</trackback:ping><description><![CDATA[在没有修Ҏ作时Q应用划分树可以在O(MlogN)旉内解x扑֌间第K的问题Q但是在引入修改Q将原序列中的某个值改为另一个|之后Q划分树׃行了?br />q时Q需要数据结构联合的思想?br />可以观察一下:<br />Q?Q区间操作:使用U段树;<br />Q?Q修改|其实是先删除再插入)和找WK:使用q树;<br />现在q两U操作都有,应该使用<span style="color: #ff0000"><strong>U段?q?/strong></span>Q?br />准确来说是线D|套^衡树Q即对原序列建立一늺D|Q其中的每个l点内套一对该结点管辖区间内的^衡树?br /><br /><1>l点cdQ结构)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">struct</span><span style="color: #000000"> seg_node {<br />    </span><span style="color: #0000ff">int</span><span style="color: #000000"> l, r, mid, lch, rch, rt;<br />} T0[MAXN0];<br /></span><span style="color: #0000ff">struct</span><span style="color: #000000"> SBT_node {<br />    </span><span style="color: #0000ff">int</span><span style="color: #000000"> v, l, r, p, sz0, sz, mul;<br />} T[MAXN];<br /></span></div>其中seg_node是线D|l点cdQSBT_node是^衡树(SBT)l点cd。需要注意的是seg_node里面的rt域(root的羃写)Q它是该l点内套的^衡树的根l点下标索引Q因为对于Q意一^衡树Q只要知道了其根l点可以遍历整|Q?br /><br /><2>建树Q?br />建树是线D|和^衡树一起徏。在建立U段树结点的时候,先徏立一늩的^衡树Qrt域置0Q,然后再在q树里面逐个插入该结点管辖区间内的所有元素即可;<br /><br /><3>修改Q?br />修改操作要注意:如果要将A[x]QA为原序列Q的g改ؓyQ则需要自向下遍历整늺D|Q将所有包含了A[x]的结点内的^衡树全部执行“删除v=A[x]Q这个可以通过真正l护一个序列得刎ͼQ再插入y”的操作;<br /><br /><4>扑֌间第K:<br />q个操作极其ȝ。需要借助二分?br />设要在区间[l, r]中找到第K。首先将[l, r]拆分成若q个U段树结点,然后二分一个值xQ在q些l点的^衡树中找到x的rankQ这里的rank指^衡树中有多少个值比x,不需要加1Q,加v来,最后再?Q就是x在[l, r]中的dơ。问题是Q设[l..r]中第K的Cؓv1Q第(K+1)的Cؓv2Q如果不存在的话Qv2=+∞Q,则[v1, v2)内的数都?#8220;WK?#8221;的。因此,不能二分数字Q而应该二分元素。设S[i]为原序列中第i的敎ͼ二分iQ然后在根结点的q树中扑ֈWi的即ؓS[i]Q再求其名次Q这L到找到dơؓK的元素ؓ止。问题还没完Q序列中可能有元素的值相同,q时可能永远也找不到WK的Q比如序? 2 3 3 3 4 5QK=4Q若“序列中比x的元素L+1”为x的名ơ,则永q也找不到第4的Q,因此Q若q样求出?#8220;名次”于{于KQ都应该下一ơ的左边界设为mid而不?mid+1)Q?#8220;名次”大于KӞ该元素肯定不是第K的Q所以下一ơ右边界设ؓ(mid-1)?br /><br />代码Q本机测最猥琐数据4s以内Q交到ZJU上TLEQ不知ؓ什么,犇指点一下,3xQ: <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: #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">#define</span><span style="color: #000000"> re3(i, l, r) for (int i=l; i<=r; 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"> MAXN0 </span><span style="color: #000000">=</span><span style="color: #000000"> </span><span style="color: #000000">110000</span><span style="color: #000000">, MAXN </span><span style="color: #000000">=</span><span style="color: #000000"> </span><span style="color: #000000">930000</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"> seg_node {<br />    </span><span style="color: #0000ff">int</span><span style="color: #000000"> l, r, mid, lch, rch, rt;<br />} T0[MAXN0];<br /></span><span style="color: #0000ff">struct</span><span style="color: #000000"> SBT_node {<br />    </span><span style="color: #0000ff">int</span><span style="color: #000000"> v, l, r, p, sz0, sz, mul;<br />} T[MAXN];<br /></span><span style="color: #0000ff">int</span><span style="color: #000000"> No0, No, n, root, rt0, a[MAXN0 </span><span style="color: #000000">>></span><span style="color: #000000"> </span><span style="color: #000000">1</span><span style="color: #000000">], b[MAXN0 </span><span style="color: #000000">>></span><span style="color: #000000"> </span><span style="color: #000000">1</span><span style="color: #000000">], l1, r1, len;<br /></span><span style="color: #0000ff">void</span><span style="color: #000000"> slc(</span><span style="color: #0000ff">int</span><span style="color: #000000"> _p, </span><span style="color: #0000ff">int</span><span style="color: #000000"> _c)<br />{<br />    T[_p].l </span><span style="color: #000000">=</span><span style="color: #000000"> _c; T[_c].p </span><span style="color: #000000">=</span><span style="color: #000000"> _p;<br />}<br /></span><span style="color: #0000ff">void</span><span style="color: #000000"> src(</span><span style="color: #0000ff">int</span><span style="color: #000000"> _p, </span><span style="color: #0000ff">int</span><span style="color: #000000"> _c)<br />{<br />    T[_p].r </span><span style="color: #000000">=</span><span style="color: #000000"> _c; T[_c].p </span><span style="color: #000000">=</span><span style="color: #000000"> _p;<br />}<br /></span><span style="color: #0000ff">void</span><span style="color: #000000"> upd(</span><span style="color: #0000ff">int</span><span style="color: #000000"> x)<br />{<br />    T[x].sz0 </span><span style="color: #000000">=</span><span style="color: #000000"> T[T[x].l].sz0 </span><span style="color: #000000">+</span><span style="color: #000000"> T[T[x].r].sz0 </span><span style="color: #000000">+</span><span style="color: #000000"> T[x].mul;<br />    T[x].sz </span><span style="color: #000000">=</span><span style="color: #000000"> T[T[x].l].sz </span><span style="color: #000000">+</span><span style="color: #000000"> T[T[x].r].sz </span><span style="color: #000000">+</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"> lrot(</span><span style="color: #0000ff">int</span><span style="color: #000000"> x)<br />{<br />    </span><span style="color: #0000ff">int</span><span style="color: #000000"> y </span><span style="color: #000000">=</span><span style="color: #000000"> T[x].p; </span><span style="color: #0000ff">if</span><span style="color: #000000"> (y </span><span style="color: #000000">==</span><span style="color: #000000"> rt0) T[rt0 </span><span style="color: #000000">=</span><span style="color: #000000"> x].p </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">else</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"> T[y].p; </span><span style="color: #0000ff">if</span><span style="color: #000000"> (y </span><span style="color: #000000">==</span><span style="color: #000000"> T[p].l) slc(p, x); </span><span style="color: #0000ff">else</span><span style="color: #000000"> src(p, x);}<br />    src(y, T[x].l); slc(x, y); T[x].sz0 </span><span style="color: #000000">=</span><span style="color: #000000"> T[y].sz0; T[x].sz </span><span style="color: #000000">=</span><span style="color: #000000"> T[y].sz; upd(y);<br />}<br /></span><span style="color: #0000ff">void</span><span style="color: #000000"> rrot(</span><span style="color: #0000ff">int</span><span style="color: #000000"> x)<br />{<br />    </span><span style="color: #0000ff">int</span><span style="color: #000000"> y </span><span style="color: #000000">=</span><span style="color: #000000"> T[x].p; </span><span style="color: #0000ff">if</span><span style="color: #000000"> (y </span><span style="color: #000000">==</span><span style="color: #000000"> rt0) T[rt0 </span><span style="color: #000000">=</span><span style="color: #000000"> x].p </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">else</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"> T[y].p; </span><span style="color: #0000ff">if</span><span style="color: #000000"> (y </span><span style="color: #000000">==</span><span style="color: #000000"> T[p].l) slc(p, x); </span><span style="color: #0000ff">else</span><span style="color: #000000"> src(p, x);}<br />    slc(y, T[x].r); src(x, y); T[x].sz0 </span><span style="color: #000000">=</span><span style="color: #000000"> T[y].sz0; T[x].sz </span><span style="color: #000000">=</span><span style="color: #000000"> T[y].sz; upd(y);<br />}<br /></span><span style="color: #0000ff">void</span><span style="color: #000000"> maintain(</span><span style="color: #0000ff">int</span><span style="color: #000000"> x, </span><span style="color: #0000ff">bool</span><span style="color: #000000"> ff)<br />{<br />    </span><span style="color: #0000ff">int</span><span style="color: #000000"> z;<br />    </span><span style="color: #0000ff">if</span><span style="color: #000000"> (ff) {<br />        </span><span style="color: #0000ff">if</span><span style="color: #000000"> (T[T[T[x].r].r].sz </span><span style="color: #000000">></span><span style="color: #000000"> T[T[x].l].sz) {z </span><span style="color: #000000">=</span><span style="color: #000000"> T[x].r; lrot(z);}<br />        </span><span style="color: #0000ff">else</span><span style="color: #000000"> </span><span style="color: #0000ff">if</span><span style="color: #000000"> (T[T[T[x].r].l].sz </span><span style="color: #000000">></span><span style="color: #000000"> T[T[x].l].sz) {z </span><span style="color: #000000">=</span><span style="color: #000000"> T[T[x].r].l; rrot(z); lrot(z);} </span><span style="color: #0000ff">else</span><span style="color: #000000"> </span><span style="color: #0000ff">return</span><span style="color: #000000">;<br />    } </span><span style="color: #0000ff">else</span><span style="color: #000000"> {<br />        </span><span style="color: #0000ff">if</span><span style="color: #000000"> (T[T[T[x].l].l].sz </span><span style="color: #000000">></span><span style="color: #000000"> T[T[x].r].sz) {z </span><span style="color: #000000">=</span><span style="color: #000000"> T[x].l; rrot(z);}<br />        </span><span style="color: #0000ff">else</span><span style="color: #000000"> </span><span style="color: #0000ff">if</span><span style="color: #000000"> (T[T[T[x].l].r].sz </span><span style="color: #000000">></span><span style="color: #000000"> T[T[x].r].sz) {z </span><span style="color: #000000">=</span><span style="color: #000000"> T[T[x].l].r; lrot(z); rrot(z);} </span><span style="color: #0000ff">else</span><span style="color: #000000"> </span><span style="color: #0000ff">return</span><span style="color: #000000">;<br />    }<br />    maintain(T[z].l, </span><span style="color: #000000">0</span><span style="color: #000000">); maintain(T[z].r, </span><span style="color: #000000">1</span><span style="color: #000000">); maintain(z, </span><span style="color: #000000">0</span><span style="color: #000000">); maintain(z, </span><span style="color: #000000">1</span><span style="color: #000000">);<br />}<br /></span><span style="color: #0000ff">int</span><span style="color: #000000"> find(</span><span style="color: #0000ff">int</span><span style="color: #000000"> _v)<br />{<br />    </span><span style="color: #0000ff">int</span><span style="color: #000000"> i </span><span style="color: #000000">=</span><span style="color: #000000"> rt0, v0;<br />    </span><span style="color: #0000ff">while</span><span style="color: #000000"> (i) {<br />        v0 </span><span style="color: #000000">=</span><span style="color: #000000"> T[i].v;<br />        </span><span style="color: #0000ff">if</span><span style="color: #000000"> (_v </span><span style="color: #000000">==</span><span style="color: #000000"> v0) </span><span style="color: #0000ff">return</span><span style="color: #000000"> i; </span><span style="color: #0000ff">else</span><span style="color: #000000"> </span><span style="color: #0000ff">if</span><span style="color: #000000"> (_v </span><span style="color: #000000"><</span><span style="color: #000000"> v0) i </span><span style="color: #000000">=</span><span style="color: #000000"> T[i].l; </span><span style="color: #0000ff">else</span><span style="color: #000000"> i </span><span style="color: #000000">=</span><span style="color: #000000"> T[i].r;<br />    }<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><span style="color: #0000ff">void</span><span style="color: #000000"> ins(</span><span style="color: #0000ff">int</span><span style="color: #000000"> _v)<br />{<br />    </span><span style="color: #0000ff">if</span><span style="color: #000000"> (</span><span style="color: #000000">!</span><span style="color: #000000">rt0) {<br />        T[</span><span style="color: #000000">++</span><span style="color: #000000">No].v </span><span style="color: #000000">=</span><span style="color: #000000"> _v; T[No].l </span><span style="color: #000000">=</span><span style="color: #000000"> T[No].r </span><span style="color: #000000">=</span><span style="color: #000000"> T[No].p </span><span style="color: #000000">=</span><span style="color: #000000"> </span><span style="color: #000000">0</span><span style="color: #000000">; T[No].sz0 </span><span style="color: #000000">=</span><span style="color: #000000"> T[No].sz </span><span style="color: #000000">=</span><span style="color: #000000"> T[No].mul </span><span style="color: #000000">=</span><span style="color: #000000"> </span><span style="color: #000000">1</span><span style="color: #000000">; rt0 </span><span style="color: #000000">=</span><span style="color: #000000"> No;<br />    } </span><span style="color: #0000ff">else</span><span style="color: #000000"> {<br />        </span><span style="color: #0000ff">int</span><span style="color: #000000"> i </span><span style="color: #000000">=</span><span style="color: #000000"> rt0, j, v0;<br />        </span><span style="color: #0000ff">while</span><span style="color: #000000"> (</span><span style="color: #000000">1</span><span style="color: #000000">) {<br />            T[i].sz0</span><span style="color: #000000">++</span><span style="color: #000000">; v0 </span><span style="color: #000000">=</span><span style="color: #000000"> T[i].v;<br />            </span><span style="color: #0000ff">if</span><span style="color: #000000"> (_v </span><span style="color: #000000">==</span><span style="color: #000000"> v0) {T[i].mul</span><span style="color: #000000">++</span><span style="color: #000000">; </span><span style="color: #0000ff">return</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"> (_v </span><span style="color: #000000"><</span><span style="color: #000000"> v0) j </span><span style="color: #000000">=</span><span style="color: #000000"> T[i].l; </span><span style="color: #0000ff">else</span><span style="color: #000000"> j </span><span style="color: #000000">=</span><span style="color: #000000"> T[i].r;<br />            </span><span style="color: #0000ff">if</span><span style="color: #000000"> (j) i </span><span style="color: #000000">=</span><span style="color: #000000"> j; </span><span style="color: #0000ff">else</span><span style="color: #000000"> </span><span style="color: #0000ff">break</span><span style="color: #000000">;<br />        }<br />        T[</span><span style="color: #000000">++</span><span style="color: #000000">No].v </span><span style="color: #000000">=</span><span style="color: #000000"> _v; T[No].l </span><span style="color: #000000">=</span><span style="color: #000000"> T[No].r </span><span style="color: #000000">=</span><span style="color: #000000"> </span><span style="color: #000000">0</span><span style="color: #000000">; T[No].sz0 </span><span style="color: #000000">=</span><span style="color: #000000"> T[No].sz </span><span style="color: #000000">=</span><span style="color: #000000"> T[No].mul </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"> (_v </span><span style="color: #000000"><</span><span style="color: #000000"> v0) slc(i, No); </span><span style="color: #0000ff">else</span><span style="color: #000000"> src(i, No);<br />        </span><span style="color: #0000ff">while</span><span style="color: #000000"> (i) {T[i].sz</span><span style="color: #000000">++</span><span style="color: #000000">; maintain(i, _v </span><span style="color: #000000">></span><span style="color: #000000"> T[i].v); i </span><span style="color: #000000">=</span><span style="color: #000000"> T[i].p;}<br />    }<br />}<br /></span><span style="color: #0000ff">void</span><span style="color: #000000"> del(</span><span style="color: #0000ff">int</span><span style="color: #000000"> x)<br />{<br />    </span><span style="color: #0000ff">if</span><span style="color: #000000"> (T[x].mul </span><span style="color: #000000">></span><span style="color: #000000"> </span><span style="color: #000000">1</span><span style="color: #000000">) {<br />        T[x].mul</span><span style="color: #000000">--</span><span style="color: #000000">;<br />        </span><span style="color: #0000ff">while</span><span style="color: #000000"> (x) {T[x].sz0</span><span style="color: #000000">--</span><span style="color: #000000">; x </span><span style="color: #000000">=</span><span style="color: #000000"> T[x].p;}<br />    } </span><span style="color: #0000ff">else</span><span style="color: #000000"> {<br />        </span><span style="color: #0000ff">int</span><span style="color: #000000"> l </span><span style="color: #000000">=</span><span style="color: #000000"> T[x].l, r </span><span style="color: #000000">=</span><span style="color: #000000"> T[x].r;<br />        </span><span style="color: #0000ff">if</span><span style="color: #000000"> (</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">!</span><span style="color: #000000">r) {<br />            </span><span style="color: #0000ff">if</span><span style="color: #000000"> (x </span><span style="color: #000000">==</span><span style="color: #000000"> rt0) T[rt0 </span><span style="color: #000000">=</span><span style="color: #000000"> l </span><span style="color: #000000">+</span><span style="color: #000000"> r].p </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">else</span><span style="color: #000000"> {<br />                </span><span style="color: #0000ff">int</span><span style="color: #000000"> p </span><span style="color: #000000">=</span><span style="color: #000000"> T[x].p; </span><span style="color: #0000ff">if</span><span style="color: #000000"> (x </span><span style="color: #000000">==</span><span style="color: #000000"> T[p].l) slc(p, l </span><span style="color: #000000">+</span><span style="color: #000000"> r); </span><span style="color: #0000ff">else</span><span style="color: #000000"> src(p, l </span><span style="color: #000000">+</span><span style="color: #000000"> r);<br />                </span><span style="color: #0000ff">while</span><span style="color: #000000"> (p) {T[p].sz0</span><span style="color: #000000">--</span><span style="color: #000000">; T[p].sz</span><span style="color: #000000">--</span><span style="color: #000000">; p </span><span style="color: #000000">=</span><span style="color: #000000"> T[p].p;}<br />            }<br />        } </span><span style="color: #0000ff">else</span><span style="color: #000000"> {<br />            </span><span style="color: #0000ff">int</span><span style="color: #000000"> i </span><span style="color: #000000">=</span><span style="color: #000000"> l, j;<br />            </span><span style="color: #0000ff">while</span><span style="color: #000000"> (j </span><span style="color: #000000">=</span><span style="color: #000000"> T[i].r) i </span><span style="color: #000000">=</span><span style="color: #000000"> j;<br />            T[x].v </span><span style="color: #000000">=</span><span style="color: #000000"> T[i].v; T[x].mul </span><span style="color: #000000">=</span><span style="color: #000000"> T[i].mul; </span><span style="color: #0000ff">int</span><span style="color: #000000"> p </span><span style="color: #000000">=</span><span style="color: #000000"> T[i].p; </span><span style="color: #0000ff">if</span><span style="color: #000000"> (i </span><span style="color: #000000">==</span><span style="color: #000000"> T[p].l) slc(p, T[i].l); </span><span style="color: #0000ff">else</span><span style="color: #000000"> src(p, T[i].l);<br />            </span><span style="color: #0000ff">while</span><span style="color: #000000"> (p) {upd(p); p </span><span style="color: #000000">=</span><span style="color: #000000"> T[p].p;}<br />        }<br />    }<br />}<br /></span><span style="color: #0000ff">int</span><span style="color: #000000"> Find_Kth(</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"> rt0, s0, m0;<br />    </span><span style="color: #0000ff">while</span><span style="color: #000000"> (i) {<br />        s0 </span><span style="color: #000000">=</span><span style="color: #000000"> T[T[i].l].sz0; m0 </span><span style="color: #000000">=</span><span style="color: #000000"> T[i].mul;<br />        </span><span style="color: #0000ff">if</span><span style="color: #000000"> (K </span><span style="color: #000000"><=</span><span style="color: #000000"> s0) i </span><span style="color: #000000">=</span><span style="color: #000000"> T[i].l; </span><span style="color: #0000ff">else</span><span style="color: #000000"> </span><span style="color: #0000ff">if</span><span style="color: #000000"> (K </span><span style="color: #000000"><=</span><span style="color: #000000"> s0 </span><span style="color: #000000">+</span><span style="color: #000000"> m0) </span><span style="color: #0000ff">return</span><span style="color: #000000"> T[i].v; </span><span style="color: #0000ff">else</span><span style="color: #000000"> {K </span><span style="color: #000000">-=</span><span style="color: #000000"> s0 </span><span style="color: #000000">+</span><span style="color: #000000"> m0; i </span><span style="color: #000000">=</span><span style="color: #000000"> T[i].r;}<br />    }<br />}<br /></span><span style="color: #0000ff">int</span><span style="color: #000000"> rank(</span><span style="color: #0000ff">int</span><span style="color: #000000"> _v)<br />{<br />    </span><span style="color: #0000ff">int</span><span style="color: #000000"> i </span><span style="color: #000000">=</span><span style="color: #000000"> rt0, tot </span><span style="color: #000000">=</span><span style="color: #000000"> </span><span style="color: #000000">0</span><span style="color: #000000">, v0;<br />    </span><span style="color: #0000ff">while</span><span style="color: #000000"> (i) {<br />        v0 </span><span style="color: #000000">=</span><span style="color: #000000"> T[i].v;<br />        </span><span style="color: #0000ff">if</span><span style="color: #000000"> (_v </span><span style="color: #000000">==</span><span style="color: #000000"> v0) {tot </span><span style="color: #000000">+=</span><span style="color: #000000"> T[T[i].l].sz0; </span><span style="color: #0000ff">return</span><span style="color: #000000"> tot;} </span><span style="color: #0000ff">else</span><span style="color: #000000"> </span><span style="color: #0000ff">if</span><span style="color: #000000"> (_v </span><span style="color: #000000"><</span><span style="color: #000000"> v0) i </span><span style="color: #000000">=</span><span style="color: #000000"> T[i].l; </span><span style="color: #0000ff">else</span><span style="color: #000000"> {tot </span><span style="color: #000000">+=</span><span style="color: #000000"> T[T[i].l].sz0 </span><span style="color: #000000">+</span><span style="color: #000000"> T[i].mul; i </span><span style="color: #000000">=</span><span style="color: #000000"> T[i].r;}<br />    }<br />    </span><span style="color: #0000ff">return</span><span style="color: #000000"> tot;<br />}<br /></span><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)<br />{<br />    T0[</span><span style="color: #000000">++</span><span style="color: #000000">No0].l </span><span style="color: #000000">=</span><span style="color: #000000"> l; T0[No0].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">; T0[No0].mid </span><span style="color: #000000">=</span><span style="color: #000000"> mid; rt0 </span><span style="color: #000000">=</span><span style="color: #000000"> </span><span style="color: #000000">0</span><span style="color: #000000">;<br />    re3(i, l, r) ins(a[i]); T0[No0].rt </span><span style="color: #000000">=</span><span style="color: #000000"> rt0;<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">int</span><span style="color: #000000"> No00 </span><span style="color: #000000">=</span><span style="color: #000000"> No0; T0[No00].lch </span><span style="color: #000000">=</span><span style="color: #000000"> mkt(l, mid); T0[No00].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); </span><span style="color: #0000ff">return</span><span style="color: #000000"> No00;} </span><span style="color: #0000ff">else</span><span style="color: #000000"> {T0[No0].lch </span><span style="color: #000000">=</span><span style="color: #000000"> T0[No0].rch </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">return</span><span style="color: #000000"> No0;}<br />}<br /></span><span style="color: #0000ff">void</span><span style="color: #000000"> fs(</span><span style="color: #0000ff">int</span><span style="color: #000000"> x)<br />{<br />    </span><span style="color: #0000ff">if</span><span style="color: #000000"> (x) {<br />        </span><span style="color: #0000ff">int</span><span style="color: #000000"> l0 </span><span style="color: #000000">=</span><span style="color: #000000"> T0[x].l, r0 </span><span style="color: #000000">=</span><span style="color: #000000"> T0[x].r;<br />        </span><span style="color: #0000ff">if</span><span style="color: #000000"> (l0 </span><span style="color: #000000">>=</span><span style="color: #000000"> l1 </span><span style="color: #000000">&&</span><span style="color: #000000"> r0 </span><span style="color: #000000"><=</span><span style="color: #000000"> r1) b[len</span><span style="color: #000000">++</span><span style="color: #000000">] </span><span style="color: #000000">=</span><span style="color: #000000"> T0[x].rt; </span><span style="color: #0000ff">else</span><span style="color: #000000"> </span><span style="color: #0000ff">if</span><span style="color: #000000"> (l0 </span><span style="color: #000000">></span><span style="color: #000000"> r1 </span><span style="color: #000000">||</span><span style="color: #000000"> r0 </span><span style="color: #000000"><</span><span style="color: #000000"> l1) </span><span style="color: #0000ff">return</span><span style="color: #000000">; </span><span style="color: #0000ff">else</span><span style="color: #000000"> {fs(T0[x].lch); fs(T0[x].rch);}<br />    }<br />}<br /></span><span style="color: #0000ff">void</span><span style="color: #000000"> C(</span><span style="color: #0000ff">int</span><span style="color: #000000"> x, </span><span style="color: #0000ff">int</span><span style="color: #000000"> _v)<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, l0, r0, mid0, v0 </span><span style="color: #000000">=</span><span style="color: #000000"> a[x], N;<br />    </span><span style="color: #0000ff">while</span><span style="color: #000000"> (i) {<br />        l0 </span><span style="color: #000000">=</span><span style="color: #000000"> T0[i].l; r0 </span><span style="color: #000000">=</span><span style="color: #000000"> T0[i].r; mid0 </span><span style="color: #000000">=</span><span style="color: #000000"> T0[i].mid; rt0 </span><span style="color: #000000">=</span><span style="color: #000000"> T0[i].rt;<br />        N </span><span style="color: #000000">=</span><span style="color: #000000"> find(v0); del(N); ins(_v); T0[i].rt </span><span style="color: #000000">=</span><span style="color: #000000"> rt0;<br />        </span><span style="color: #0000ff">if</span><span style="color: #000000"> (x </span><span style="color: #000000"><=</span><span style="color: #000000"> mid0) i </span><span style="color: #000000">=</span><span style="color: #000000"> T0[i].lch; </span><span style="color: #0000ff">else</span><span style="color: #000000"> i </span><span style="color: #000000">=</span><span style="color: #000000"> T0[i].rch;<br />    }<br />    a[x] </span><span style="color: #000000">=</span><span style="color: #000000"> _v;<br />}<br /></span><span style="color: #0000ff">int</span><span style="color: #000000"> Q(</span><span style="color: #0000ff">int</span><span style="color: #000000"> K)<br />{<br />    len </span><span style="color: #000000">=</span><span style="color: #000000"> </span><span style="color: #000000">0</span><span style="color: #000000">; fs(root);<br />    </span><span style="color: #0000ff">int</span><span style="color: #000000"> ls </span><span style="color: #000000">=</span><span style="color: #000000"> </span><span style="color: #000000">1</span><span style="color: #000000">, rs </span><span style="color: #000000">=</span><span style="color: #000000"> n, mids, midv, tot;<br />    </span><span style="color: #0000ff">while</span><span style="color: #000000"> (ls </span><span style="color: #000000"><</span><span style="color: #000000"> rs) {<br />        mids </span><span style="color: #000000">=</span><span style="color: #000000"> ls </span><span style="color: #000000">+</span><span style="color: #000000"> rs </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">; rt0 </span><span style="color: #000000">=</span><span style="color: #000000"> T0[root].rt; midv </span><span style="color: #000000">=</span><span style="color: #000000"> Find_Kth(mids);<br />        tot </span><span style="color: #000000">=</span><span style="color: #000000"> </span><span style="color: #000000">1</span><span style="color: #000000">; re(i, len) {rt0 </span><span style="color: #000000">=</span><span style="color: #000000"> b[i]; tot </span><span style="color: #000000">+=</span><span style="color: #000000"> rank(midv);}<br />        </span><span style="color: #0000ff">if</span><span style="color: #000000"> (tot </span><span style="color: #000000"><=</span><span style="color: #000000"> K) ls </span><span style="color: #000000">=</span><span style="color: #000000"> mids; </span><span style="color: #0000ff">else</span><span style="color: #000000"> rs </span><span style="color: #000000">=</span><span style="color: #000000"> mids </span><span style="color: #000000">-</span><span style="color: #000000"> </span><span style="color: #000000">1</span><span style="color: #000000">;<br />    }<br />    rt0 </span><span style="color: #000000">=</span><span style="color: #000000"> T0[root].rt; </span><span style="color: #0000ff">return</span><span style="color: #000000"> Find_Kth(ls);<br />}<br /></span><span style="color: #0000ff">int</span><span style="color: #000000"> main()<br />{<br />    </span><span style="color: #0000ff">int</span><span style="color: #000000"> tests, m, x, y, K;<br />    </span><span style="color: #0000ff">char</span><span style="color: #000000"> ch;<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">tests);<br />    re(testno, tests) {<br />        scanf(</span><span style="color: #000000">"</span><span style="color: #000000">%d%d</span><span style="color: #000000">"</span><span style="color: #000000">, </span><span style="color: #000000">&</span><span style="color: #000000">n, </span><span style="color: #000000">&</span><span style="color: #000000">m); No0 </span><span style="color: #000000">=</span><span style="color: #000000"> No </span><span style="color: #000000">=</span><span style="color: #000000"> </span><span style="color: #000000">0</span><span style="color: #000000">;<br />        re(i, n) 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">a[i]); ch </span><span style="color: #000000">=</span><span style="color: #000000"> getchar();<br />        root </span><span style="color: #000000">=</span><span style="color: #000000"> mkt(</span><span style="color: #000000">0</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">);<br />        re(i, m) {<br />            ch </span><span style="color: #000000">=</span><span style="color: #000000"> getchar();<br />            </span><span style="color: #0000ff">if</span><span style="color: #000000"> (ch </span><span style="color: #000000">==</span><span style="color: #000000"> </span><span style="color: #000000">'</span><span style="color: #000000">C</span><span style="color: #000000">'</span><span style="color: #000000">) {<br />                scanf(</span><span style="color: #000000">"</span><span style="color: #000000">%d%d%*c</span><span style="color: #000000">"</span><span style="color: #000000">, </span><span style="color: #000000">&</span><span style="color: #000000">x, </span><span style="color: #000000">&</span><span style="color: #000000">y);<br />                C(</span><span style="color: #000000">--</span><span style="color: #000000">x, y);<br />            } </span><span style="color: #0000ff">else</span><span style="color: #000000"> {<br />                scanf(</span><span style="color: #000000">"</span><span style="color: #000000">%d%d%d%*c</span><span style="color: #000000">"</span><span style="color: #000000">, </span><span style="color: #000000">&</span><span style="color: #000000">l1, </span><span style="color: #000000">&</span><span style="color: #000000">r1, </span><span style="color: #000000">&</span><span style="color: #000000">K);<br />                l1</span><span style="color: #000000">--</span><span style="color: #000000">; r1</span><span style="color: #000000">--</span><span style="color: #000000">; printf(</span><span style="color: #000000">"</span><span style="color: #000000">%d\n</span><span style="color: #000000">"</span><span style="color: #000000">, Q(K));<br />            }<br />        }<br />    }<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><img src ="http://www.shnenglu.com/MatoNo1/aggbug/149605.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 21:53 <a href="http://www.shnenglu.com/MatoNo1/archive/2011/06/27/149605.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Splay Tree处理区间问题的几道好题及ȝhttp://www.shnenglu.com/MatoNo1/archive/2011/06/25/149425.htmlMato_No1Mato_No1Sat, 25 Jun 2011 03:21:00 GMThttp://www.shnenglu.com/MatoNo1/archive/2011/06/25/149425.htmlhttp://www.shnenglu.com/MatoNo1/comments/149425.htmlhttp://www.shnenglu.com/MatoNo1/archive/2011/06/25/149425.html#Feedback2http://www.shnenglu.com/MatoNo1/comments/commentRss/149425.htmlhttp://www.shnenglu.com/MatoNo1/services/trackbacks/149425.htmlQ?QRobotic SortQ?a title="HDU1890" >HDU1890?a title="ZJU2985" >ZJU2985Q?br />本题主要考察的是Ҏc问题,序列中给定值的索引问题?br />当Splay Tree用来处理一个序列的时候,其关键字是序列中元素的下标Q而不是元素的倹{这P如果要查扑ֺ列中l定的值的位置Q假讑ֺ列中L两个元素的g相等Q看h无法实现。其实也是有办法实现的:因ؓ元素在树中的下标是永q不变的Q也是Q设q个序列为AQ如果A[i]在插入Splay Tree时的下标为jQ那么在A[i]被删除之前,其下标一直是jQ永q不会变Q注意元素在序列中的下标和在树中的下标是不同的)。利用这一性质可以解决l定值的索引问题?br />对于本题Q每ơ将从序列中Wi的元素到序列中Wi个元素(q里假定元素下标是从1开始的Q而不是从0开始)之间的所有元素反转,q输出第i的元素在反转之前的在序列中的下标。设B[i]为第i的数的初始位置QS[i]?span style="color: #ff0000">初始位置在第i位的元素的下标,B[i]和S[i]都可以通过预处理得到。然后,每次交换前,求出S[B[i]]在树中的排名Q基本操作)Q再?Q因为有边界l点Q就是该元素目前的位|,而序列中Wi个元素就是树中第(i+1)的元素Q再执行交换卛_?br />不过需要千万注意的是本题的标记问题Q在求S[B[i]]在树中的排名Ӟ有可能其先l点上有标记Q需要先遍历其所有的先l点Q再逆向下放标记Q标记只能自向下传Q。另外在交换的时候需要求出S[B[i]]的后l,在求后的过E中需要查找,此时千万别忘了下放标讎ͼȝ_凡是有查扄地方Q就有dmQ?br />代码Q本沙茶太弱了,是抄别h的,因此其算法和上面ȝ的可能有差别Q神犇不要鄙视)
Q?QSuperMemoQ?a title="PKU3580" >PKU3580Q?br />本题?个操作中Qadd、reverse、insert、delete、min都不难搞Q而revolve操作需要涉及到区间交换?br />可以发现Q所谓的旋{其实是交换两个盔R区间Q这对于功能极强的Splay Tree来说Ҏ不难搞?br />设这两个盔R区间为[x, y]与[y+1, z]Q假讑֮们均非空Q也是x<=y<zQ因其中臛_有一个区间是I区_则交换没有意义)Q先扑ֈ树中x的前P与z的后lSQ这里x、z{指的都是对应的l点Q下同)Q将P伸展到根、将S伸展到根的右子结点处Q则S的左子树pC区间[x, z]。然后,设S的左子树的根l点Q也是S的左子结点)为NQ在q棵子树中找到第1的l点P0与第(y-x+2)的l点S0Q这需要涉及到扑֭树内WK的操作Q只要把找整|WK的操作的root改ؓN卛_Q,它们分别表示x?y+1)Q这样将P0伸展到N处,S0伸展到N的右子结点处Q显然P0无左子树QS0的左子树T1表示区间[x+1, y]QS0的右子树T2表示区间[y+2, z]。然后,先将S0从P0的右子结点移动到P0的左子结点,再将T1作ؓP0的右子树Q注意移动是两步Q插入和删除Q。这h子树的中序遍历l果变成了S0->T2->P0->T1Q也是[y+1, z]∪[x, y]?br />另外本题的标记有炚w搞,只需注意rev是逆向标记Q以及查找与dm共存p了?br />代码
Q?QPlay with Chain(HDU3487)
q个cx马好说的,里面的操作在SuperMemo里都有;
代码
Q?Q?a title="AHOI2006 文本~辑?editor)" >AHOI2006 文本~辑?editor)
q题在这一c题里面水的。对于光标,只要用一个值来l护p了?br />另外注意本题极ؓ猥琐?点(题目中米有说明)Q一是最初的文本q不是空的,而是有一个空|二是执行GET操作时光标可能位于文本末,此时应输出空|
代码
Q?QHFTSC2011 高精度计器(apc)Q题目见q个帖子Q?br />q题反映Z一个很囧的问题Q有些信息会被rev整体破坏?br />本题中的操作都是常见操作Q但是本题所需要维护的信息却不是那么容易维护。本题要求维护一子树中所有结Ҏ表示的元素序列(中序遍历l果Q模一个指定的M的倹{设F[i]为R^i mod M的|q里R是进Ӟ也就是题目中的KQ,则有Q?br />T[x].mod = (T[T[x].c[0]].mod * F[T[T[x].c[1]].sz + 1] + T[x].v * F[T[T[x].c[1]].sz] + T[T[x].c[1]].mod) % M;
q个式子其实是很好理解的?br />关键是,本题的猥琐之处ƈ不在此。注意本题的rev操作Q它会整体改变树中所有结Ҏ记录的mod|q时Q如果再用上面这个式子来l护T[x].modQ就会出错,因ؓ此时引用到的T[T[x].c[0]].mod和T[T[x].c[1]].mod都是q时的。解册一问题只有一U方法:记录“逆mod”(rmod)Q意思是整个元素序列反转后的modQ即Q?br />T[x].rmod = (T[T[x].c[1]].rmod * F[T[T[x].c[0]].sz + 1] + T[x].v * F[T[T[x].c[0]].sz] + T[T[x].c[0]].rmod) % M;
q样Q在反{某序列的时候,直接根l点的mod值和rmodg换就行了?br />像modq样会被反{操作整体破坏的信息还有很多,比如NOI2005 sequence里面的lmax和rmax。如果真的遇到这cM息,只有采用上面的方法?br />另外Q本题第6??0个点有误?br />代码

现在Splay Tree差不多弄完了Q接下来q有N多知名的、不知名的高U数据结?#8230;…旉MS有些不够用了?#8230;…


Mato_No1 2011-06-25 11:21 发表评论
]]>
q树调试技?/title><link>http://www.shnenglu.com/MatoNo1/archive/2011/06/23/149218.html</link><dc:creator>Mato_No1</dc:creator><author>Mato_No1</author><pubDate>Wed, 22 Jun 2011 16:07:00 GMT</pubDate><guid>http://www.shnenglu.com/MatoNo1/archive/2011/06/23/149218.html</guid><wfw:comment>http://www.shnenglu.com/MatoNo1/comments/149218.html</wfw:comment><comments>http://www.shnenglu.com/MatoNo1/archive/2011/06/23/149218.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.shnenglu.com/MatoNo1/comments/commentRss/149218.html</wfw:commentRss><trackback:ping>http://www.shnenglu.com/MatoNo1/services/trackbacks/149218.html</trackback:ping><description><![CDATA[q树操作,其是Splay Tree的区间操作(当线D|用的那种Q,代码长且极易搞疵Q当操作多的时候,甚至可能调试的时间比写代码的旉都长Q?br />q里来ȝ一下^衡树在实际应用(~程Q中的易늂和调试技巧?br />【^衡树Q这里主要指Splay TreeQ的操作?br />q个MS前面已经ȝq了Q主要分以下几类Q?br />Q?Q基本操作:查找、单l点插入、单l点删除、找WK、求l点的排名、找指定l点的前和后Q?br />Q?Q进阶操作:扄定的值在树中的前和后、对一个序列徏q树、插入整子树、删除整子树;<br />Q?Q区间操作(与线D|的结合)Q标讎ͼ自顶向下Q;<br />Q?Q区间操作(与线D|的结合)Q最大倹{d{自底向上维护的信息Q?br />Q?Q一些特别猥琐的操作Q比如PKU3580的revolveQ;<br />【主要函数及其易늂?br />Q?Qvoid sc(int _p, int _c, bool _d);<br />_p的_d子结点(0?叻I|ؓ_cQ这个就三句话,应该不会搞疵Q?br />Q?Qvoid upd(int x);<br />更新x记录的一些信息(自底向上l护的信息,包括大小域szQ,q个Q有几个信息写几句话就行了Q不易搞疵;<br />Q?Qvoid rot(int x);<br />旋{操作Q将x旋{到其父结点的位置。这个函C有两个易늂Q一是若x的父l点为根Q则需要在旋{后将根置为xQ且x的父l点|ؓ0Q特别注意这个)Q二是若x的父l点不ؓ根,则需要将x的父l点的父l点的对应子l点Q原来是x的父l点的那个)|ؓxQ另外旋转完成后别忘了更斎ͼ<br />Q?Qvoid splay(int x, int r);<br />伸展操作Q将x伸展到r的子l点处,q个操作是最核心的操作,只要C了过E,且rot不搞疵,q个也就不会搞疵Q?br />Q?Qvoid dm(int x);<br />对于有标记的l点的下放标记操作,极易疵!<br />首先Q对于Q何结点,标记一打上必ȝ即生效,因此除了x的标记取消、x的两个子l点Q如果存在的话)打上标记外,q要更新两个子结点的一些域Q当然这里更新千万不能用upd更新Q;<br />其次Q要搞清楚x的每一个标记的cdQ是叠加型标讎ͼ如整体加上某一个数的标讎ͼ、覆盖型标记Q如整体|ؓ某一个数的标讎ͼq是逆向标记Q如是否{q的标记Q因为翻转两ơ等于没转)Q然后在下放标记的时候注意写法(因ؓx的子l点原来可能也有标记Q此时只有覆盖型标记需要将x的子l点的原来的标记覆盖掉,对于叠加型标讎ͼ应ؓ加法q算Q对于逆向标记Q应为取反操作,q有其它cd的标记分别处理)Q?br />最后还有一点,是x的左子结Ҏ叛_l点可能不存在(0Q,此时׃能对q里?L点下放标记?br />Q?Qint Find_Kth(int x, int K);<br />在以l点x为根的子树中扄K的l点Q返回结点编P若省略xQ默认x=rootQ即在整|中找Q;<br />q个一般不会搞疵,注意两个地方卛_Q一是有mul域的时候需要考虑mul域,二是l点如果有标讎ͼ需要在扄时候下放标记。(凡是查找操作Q包括插入新l点时的查找Q在查找q程中必M断下放标讎ͼ因ؓ查找之后很可能就要展)Q?br />Q?Qvoid ins(int _v);<br />       void ins(int x, int _v)<br />插入一个gؓ_v的结炏V前者是普通插入,后者是用Splay Tree处理序列Q当U段树用Q时的插入,表示在第x的l点后插入;<br />前者注意有三种情况Q树为空Q树非空且gؓ_v的结点不存在Q树非空且gؓ_v的结点已存在Q?br />后者需要注意,在将Wx的l点伸展到根Q将W?x+1)的l点伸展到根的右子结点,再插入后Q需要upd上述两个l点Q注意upd序Q;<br />Q?Qvoid del(int x);<br />结点x删除。这个一般不会搞疵,唯一要注意的一Ҏ删除后的updQ?br />Q?Q打标记操作Qadd、reverse、makesame{)Q?br />其实打标记操作的代码量是很少的,关键是对于不同标记要分别处理,同(5Q;<br />Q?0Q各U询问操作:<br />q个直接调出相应的域卛_Q几乎不可能搞疵Q?br />Q?1Q极其猥琐的操作Qrevolve{)Q?br />q个属于最易疵的操作(否则׃C出其猥琐了)Q?br />首先要搞清楚q个操作的具体过E,不要q具体过E都搞疵了,q样写出来的代码肯定是疵的;<br />然后Q注意一些非常猥琐的l节问题Q很多时候,本沙茉是栽在细节上的)Q?br />另外Q这些操作中一般都会出现多ơ展,别忘了展后的updQ?br />Q?2Q其它易늂Q?br />[1]“Ud”是由“插入”?#8220;删除”两部分组成的Q因此凡是涉及到“Ud”cȝ操作Q如某子树或某个l点Ud到另一个位|等Q,必须要同时出?#8220;插入”?#8220;删除”Q而不能只插入不删除;<br />[2]注意查主函数main()中是否有搞疵的地方;<br /><br />易疵点也p么多了,下面是调试技巧:<br />【Splay Tree调试技巧?br />Q?Q先用样例调试,保证样例能够通过Q注意,样例中必d含所有题目中l出的操作,如果不是q样Q那在调试完样例后还要加一l包含所有题目中l出的操作的数据)Q?br />Q?Q然后用mkdt造大数据Q一般^衡树操作题的合法数据都不N,只要注意别越界就行了Q?br />Q?Q在调试q程中应不断量增大数据规模Q因为在能找出问题的情况下,数据规模小好Q?br />Q?Q如果调试过E中发现d@环或者REQ?br />[1]首先输出每个操作Q找出是在哪个操作处Z问题Q?br />[2]q入该操作内部检查,也就是把该操作的代码M遍,一般都能找出问题;<br />[3]如果找不出问题,可以q入该操作内部跟t检查;<br />[4]如果跟踪查仍然没扑և问题Q那可能是该操作是对的,而其它操作出了问题,此时可以弄一个vstQ把整棵树遍历一下,扑և真正出问题的操作Q{[2]Q?br />Q?Q排除了d@环或RE后,接下来就是检查输出结果是否正了Q?br />[1]对于规模数据可人工计算查,对于较大规模数据则必采用对照方法,卛_一个模拟法的代码,保证该代码正,然后q行对照Q?br />[2]如果发现加入遍历Ӟl果正确Q但L遍历后结果不正确Q则表明是处理结Ҏ记的时候出了问题(因ؓ在遍历过E中需要下放标讎ͼQ进入dm或加标记操作中检查即可;<br />[3]其它情况下,可以在遍历中输出整个序列Q或整棵树)Q进行对照,扑և问题所在;<br />[4]如果数据q大Q操作过多,人工分析旉较长Q就只能采用M码的方式查了Q?br />Q?Q最后,用mkdt造一个最大规模的数据Q检查是否TLE、是否越界(数组是否开)Q?br />如果以上各点全部通过Q就可以宣布AC了?br /><img src ="http://www.shnenglu.com/MatoNo1/aggbug/149218.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-23 00:07 <a href="http://www.shnenglu.com/MatoNo1/archive/2011/06/23/149218.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>【NOI2005 l护数列(sequence)】Splay Tree处理序列问题http://www.shnenglu.com/MatoNo1/archive/2011/06/21/149121.htmlMato_No1Mato_No1Tue, 21 Jun 2011 08:06:00 GMThttp://www.shnenglu.com/MatoNo1/archive/2011/06/21/149121.htmlhttp://www.shnenglu.com/MatoNo1/comments/149121.htmlhttp://www.shnenglu.com/MatoNo1/archive/2011/06/21/149121.html#Feedback0http://www.shnenglu.com/MatoNo1/comments/commentRss/149121.htmlhttp://www.shnenglu.com/MatoNo1/services/trackbacks/149121.html【原题见q里?br />本题是Splay Tree处理序列问题Q也是当线D|用)的一个典型例题?br />
Splay Tree之所以可以当U段树用Q是因ؓ它可以支持一个序列,然后?#8220;左端前趋伸展到根Q右端后l展到根的叛_l点Q取根的叛_l点的左子结?#8221;q种伸展ҎQ对一个序列中的一整段q行整体操作。由于要防止出现前趋或后l不存在的情况,需要在q个序列的两端加入两个边界结点,要求其g能媄响到l点各种记蝲信息的维护(多取0?#8734;?∞Q。这两个边界l点在树中永q存在,不会被删除?br />
Q?Q结点的引用Q?br />在当U段树用的Splay Tree中,真正的关键字是下标而不是|因此Q?#8220;序列中第i个结?#8221;实际上对应的?#8220;树中W?i+1)的l点”Q因为左边还有一个边界结点)Q这p明在对结点引用时需要找WK的操作。因此,下面?#8220;l点x”指的?#8220;树中W?x+1)的l点”?br />Q?Q标讎ͼ
在线D|中,如果对一个结Ҏ表示的线D|体进行了某种操作Q需要在q个l点上打上一个标讎ͼ在下一ơ再扑ֈq个l点Ӟ其标记就会下攑ֈ其两个子l点上。在Splay Tree中也可以引入标记。比如要对[2, 6]q一D进行整体操作,将l点1伸展到根的位|,结?伸展到根的右子树的位|,然后l点7的左子树pC[2, 6]q一D,对这子树的根结Ҏ上标记ƈ立即生效Q必L立即生效Q而不是等下一ơ引用再生效Q,也就是立x变该l点记录的一些信息的倹{如果下ơ再ơ引用到q个l点Q就要将其标C攑ֈ其两个子l点处;
需要注意的一ҎQ如果要伸展某个l点x到r的子l点的位|,必M证从x原来的位|到r的这个子l点Qx伸展后的位置Q上的所有结点上均没有标讎ͼ否则׃D标记混ؕ。因此,必须首先扑ֈq个l点xQ在此过E中不断下放标记?br />Q?Q自底向上维护的信息Q?br />标记可以看成一U自向下维护的信息。除了标C外,作ؓ“U段?#8221;Q往往q要l护一些自底向上维护的信息。比如在sequenceq题中,有lmaxQ左D连l最大和Q、rmaxQ右D连l最大和Q、midmaxQ全D连l最大和Q以及sumQ全D|dQ等信息要维护。对于这cM东其实也很好办,因ؓ子树大小Qsz域)是一U自底向上维护的信息Q因此对于这些信息只要按照维护sz域的办法l护卛_Q统一写在upd函数里)。唯一的不同点是打标记时它们的值可能要改变?br />Q?Q对q箋插入的结点徏树:
本题的插入不是一个一个插入,而是一下子插入一整段Q因此需要先它们徏成一|。一般徏树操作都是递归的,q里也一栗设目前要对A[l..r]建树QA为待插入序列Q,若l>r则退出,否则扑ֈ位于中间的元素mid = l + r >> 1Q将A[mid]作根Q再对A[l..mid-1]建左子树Q对A[mid+1..r]建右子树卛_。这样可以保证一开始徏的就是一^衡树Q减常数因子?br />Q?Q回收空_
Ҏ本题的数据范围提C,插入的结ҎL最多可能达?000000Q但在Q何时L中最多只?00002个结点(包括两个边界Q,此时Z节省I间Q可以采用@环队列回收空间的Ҏ。即Q一开始将所有的可用I间Q可用下标,本题?~500002Q存在@环队列Q里,同时讄头尾指针front和rearQ每ơ如果有新结Ҏ入,取出Q[front]q作为新l点的下标,如果有结点要删除Q本题是一ơ删除整子树,因此在删除后需要分别回收它们的I间Q,则从rear开始,每个删除的l点的下标放回到Q里。当Ӟq种Ҏ是要牺牲一定的旉的,因此在空间不是特别吃紧的情况下不要用?br />
?012q??6日更新?br />今天重写sequence的时候,U然发现加入的边界点可能会对lmax、rmax、midmax{的l护造成影响Q当序列中所有的值都是负数时Q若边界点的D?Q将使这3个g?Q所以,边界点的值应设ؓ-INFQ不会媄响到sumQ因为可以单独调出[l, r]的sumQ避开边界Q。这p明ƈ非所有这L题中都可以设|边界点Q比如HFTSC2011的那题就不行Q,如果边界点会对维护的信息造成影响Q就不能讄边界点,在各个操作中Q分4U情况判断。(代码已经修改Q?br />
下面上代码了Q?
#include <iostream>
#include 
<stdio.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++)
const int MAXN = 500002, NOSM = -2000, INF = ~0U >> 2;
struct node {
    
int v, c[2], p, sz, sum, lmax, rmax, midmax, sm;
    
bool rev, d;
} T[MAXN 
+ 1];
int root, Q[MAXN + 1], front, rear, a[MAXN], len, res;
int max(int SS0, int SS1)
{
    
return SS0 >= SS1 ? SS0 : SS1;
}
int max(int SS0, int SS1, int SS2)
{
    
int M0 = SS0 >= SS1 ? SS0 : SS1; return M0 >= SS2 ? M0 : SS2;
}
void newnode(int n, int _v)
{
    T[n].v 
= T[n].sum = T[n].lmax = T[n].rmax = T[n].midmax = _v; T[n].c[0= T[n].c[1= 0; T[n].sz = 1; T[n].sm = NOSM; T[n].rev = 0;
}
void sc(int _p, int _c, bool _d)
{
    T[_p].c[_d] 
= _c; T[_c].p = _p; T[_c].d = _d;
}
void sm_opr(int x, int SM)
{
    T[x].sum 
= T[x].sz * SM;
    
if (SM > 0) T[x].lmax = T[x].rmax = T[x].midmax = T[x].sum; else T[x].lmax = T[x].rmax = T[x].midmax = SM;
}
void rev_opr(int x)
{
    
int c0 = T[x].c[0], c1 = T[x].c[1]; sc(x, c0, 1); sc(x, c1, 0);
    
int tmp = T[x].lmax; T[x].lmax = T[x].rmax; T[x].rmax = tmp;
}
void dm(int x)
{
    
int SM0 = T[x].sm;
    
if (SM0 != NOSM) {
        T[x].v 
= T[T[x].c[0]].sm = T[T[x].c[1]].sm = SM0; T[x].sm = NOSM;
        sm_opr(T[x].c[
0], SM0); sm_opr(T[x].c[1], SM0);
    }
    
if (T[x].rev) {
        T[T[x].c[
0]].rev = !T[T[x].c[0]].rev; T[T[x].c[1]].rev = !T[T[x].c[1]].rev; T[x].rev = 0;
        rev_opr(T[x].c[
0]); rev_opr(T[x].c[1]);
    }
}
void upd(int x)
{
    
int c0 = T[x].c[0], c1 = T[x].c[1];
    T[x].sz 
= T[c0].sz + T[c1].sz + 1;
    T[x].sum 
= T[c0].sum + T[c1].sum + T[x].v;
    T[x].lmax 
= max(T[c0].lmax, T[c0].sum + T[x].v + max(T[c1].lmax, 0));
    T[x].rmax 
= max(T[c1].rmax, max(T[c0].rmax, 0+ T[x].v + T[c1].sum);
    T[x].midmax 
= max(T[c0].midmax, T[c1].midmax, max(T[c0].rmax, 0+ T[x].v + max(T[c1].lmax, 0));
}
void rot(int x)
{
    
int y = T[x].p; bool d = T[x].d;
    
if (y == root) {root = x; T[root].p = 0;} else sc(T[y].p, x, T[y].d);
    sc(y, T[x].c[
!d], d); sc(x, y, !d); upd(y);
}
void splay(int x, int r)
{
    
int p; while ((p = T[x].p) != r) if (T[p].p == r) rot(x); else if (T[x].d == T[p].d) {rot(p); rot(x);} else {rot(x); rot(x);} upd(x);
}
int Find_Kth(int K)
{
    
int i = root, S0;
    
while (i) {
        dm(i); S0 
= T[T[i].c[0]].sz + 1;
        
if (K == S0) breakelse if (K < S0) i = T[i].c[0]; else {K -= S0; i = T[i].c[1];}
    }
    
return i;
}
int mkt(int l, int r)
{
    
if (l > r) return 0;
    
int n0 = Q[front], mid = l + r >> 1if (front == MAXN) front = 1else front++;
    newnode(n0, a[mid]); 
int l_r = mkt(l, mid - 1), r_r = mkt(mid + 1, r);
    sc(n0, l_r, 
0); sc(n0, r_r, 1); upd(n0); return n0;
}
void ins(int pos)
{
    
int P0 = Find_Kth(pos); splay(P0, 0); int P1 = Find_Kth(pos + 1); splay(P1, root); sc(P1, mkt(0, len - 1), 0); upd(P1); upd(P0);
}
void era(int x)
{
    
if (!x) return;
    
if (rear == MAXN) rear = 1else rear++; Q[rear] = x;
    era(T[x].c[
0]); era(T[x].c[1]);
}
void del(int l, int r)
{
    
int P0 = Find_Kth(l - 1); splay(P0, 0); int P1 = Find_Kth(r + 1); splay(P1, root); 
    
int root0 = T[P1].c[0]; sc(P1, 00); upd(P1); upd(P0); era(root0);
}
void mksame(int l, int r, int x)
{
    
int P0 = Find_Kth(l - 1); splay(P0, 0); int P1 = Find_Kth(r + 1); splay(P1, root); 
    
int n = T[P1].c[0]; T[n].sm = x; sm_opr(n, x); upd(P1); upd(P0);
}
void reve(int l, int r)
{
    
int P0 = Find_Kth(l - 1); splay(P0, 0); int P1 = Find_Kth(r + 1); splay(P1, root); 
    
int n = T[P1].c[0]; T[n].rev = !T[n].rev; rev_opr(n); upd(P1); upd(P0);
}
int get_sum(int l, int r)
{
    
int P0 = Find_Kth(l - 1); splay(P0, 0); int P1 = Find_Kth(r + 1); splay(P1, root); 
    
int n = T[P1].c[0]; return T[n].sum;
}
int max_sum()
{
    
return T[root].midmax;
}
void prepare()
{
    T[
0].sz = T[0].sum = T[0].lmax = T[0].rmax = T[0].midmax = 0;
    front 
= 3; rear = MAXN; re1(i, MAXN) Q[i] = i;
    newnode(
1-INF); newnode(2-INF); sc(121); root = 1; T[root].p = 0;
}
int main()
{
    freopen(
"sequence.in""r", stdin);
    freopen(
"sequence.out""w", stdout);
    prepare();
    
int m, l, r, x;
    scanf(
"%d%d"&len, &m); char ch = getchar(), str[1000];
    re(i, len) scanf(
"%d"&a[i]); ins(1);
    re(i, m) {
        scanf(
"%s", str);
        
if (!strcmp(str, "INSERT")) {scanf("%d%d"&l, &len); re(i, len) scanf("%d"&a[i]); ins(++l);}
        
if (!strcmp(str, "DELETE")) {scanf("%d%d"&l, &r); r += l++; del(l, r);}
        
if (!strcmp(str, "MAKE-SAME")) {scanf("%d%d%d"&l, &r, &x); r += l++; mksame(l, r, x);}
        
if (!strcmp(str, "REVERSE")) {scanf("%d%d"&l, &r); r += l++; reve(l, r);}
        
if (!strcmp(str, "GET-SUM")) {scanf("%d%d"&l, &r); r += l++; printf("%d\n", get_sum(l, r));}
        
if (!strcmp(str, "MAX-SUM")) printf("%d\n", max_sum());
        ch 
= getchar();
    }
    fclose(stdin); fclose(stdout);
    
return 0;
}

最后把我的q个代码与BYVoid犇的本题代码进行测试比较,l果QBYVoid犇的代码见q里Q:

BYVoid犇的:


本沙茶的Q?br />

【相兌文?br />

Mato_No1 2011-06-21 16:06 发表评论
]]>
Splay Tree 重复ơ数mul以及一些进阶操?/title><link>http://www.shnenglu.com/MatoNo1/archive/2011/06/21/149067.html</link><dc:creator>Mato_No1</dc:creator><author>Mato_No1</author><pubDate>Tue, 21 Jun 2011 03:31:00 GMT</pubDate><guid>http://www.shnenglu.com/MatoNo1/archive/2011/06/21/149067.html</guid><wfw:comment>http://www.shnenglu.com/MatoNo1/comments/149067.html</wfw:comment><comments>http://www.shnenglu.com/MatoNo1/archive/2011/06/21/149067.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.shnenglu.com/MatoNo1/comments/commentRss/149067.html</wfw:commentRss><trackback:ping>http://www.shnenglu.com/MatoNo1/services/trackbacks/149067.html</trackback:ping><description><![CDATA[?#8230;…最q两天光儡刷题忘了ȝ?#8230;…正好现在把ȝ的东东全部补上吧?#8230;…<br /><br />【重复次数mul?br />在前面第一ȝSplay Tree的时候就提到了结点的重复ơ数(mul)域,q个东东至今在网上还c看见有犇用Q在本沙茶见q的范围内)Q但是不可否认的是这个域在某些情况下几乎?#8220;必须使用”的?br />所谓重复次敎ͼ是树中所有?v)相同的结点全部合q成一个,q些l点的M数就是合q后的结点的mul倹{比如,在一늩树中插入3个gؓ5的结点后Q在使用mul域的情况下,树中只有一个结点,其vgؓ5Qmulgؓ3?br />在^衡树中,值相同的l点实非常事。按照二叉查找树的定义:“要么是一늩树,要么是一|以下条件的非空树:根结点左子树中所有结点的值均于根结点,根结点右子树中所有结点的值均大于根结点,且根的左叛_树均Z叉查找树”Q在二叉查找树中Q是不应该出现值相同的l点的。可是在实际问题中,出现值相同的l点几乎是不可避免的。此Ӟ树的定义׃变得非常模糊Q也是要把二叉查找树定义中?#8220;于”全部改ؓ“于{于”Q?#8220;大于”全部改ؓ“大于{于”。这样定义的树在一般情况下也米有神马问题,但是在找前趋(Pred)和找后(Succ)操作中,问题来了。因为根l点的前和后的值可能与根结点相{(比如 HNOI2004 宠物收养所 那一题)Q这Ӟ根结点的前趋既有可能在左子树里,也有可能在右子树里,根结点的后也一栗此Ӟq两个操作就无法q行了?<br />【mul域的l护?br />mul域其实可以看成结点的一个本w属性,和v一栗因此在旋{、展操作中Ml点的mul值都是不会改变的。可能改变结点mul值的地方只有两处Q一是插入,二是删除。在插入一个gؓ_v的结点的时候,如果发现gؓ_v的结点在树中已经存在Q则只会这个结点的mul值加1Q而不是真正插入一个新的结炏V同LQ在删除一个结点的时候,如果q个l点的mul值大?Q则只会这个结点的mul值减1Q而不是真正删除?br />【mul域的作用?br />mul域最主要的作用就是解军_相同的l点对于某些操作的媄响。另外,mul域的引入可以减少树中l点的M敎ͼ其是当插入的结Ҏ很多而结点的值的范围不大的时候)Q从而降低时间复杂度Q准来说可以降低常敎ͼ?br />【Splay Tree的进阶操作?br /><1>N根结点的前趋和后l?br />Splay Tree׃有展操作,可以要求前或后的点伸展到根再求前趋或后l。如果要不通过伸展操作找一个非根结点的前趋或后l怎么办?<br />设这个结点ؓx。如果x有左子结点,则x的前就是x的左子结点的右链上的最后一个结点;如果x没有左子l点Q则x的前就是从x开始往上(往x的祖先)查找Q直到找到第一个是其父l点的右子结点的l点为止Q则q个l点的父l点是x的前(或者说Q就是不断沿着x的父l点往上找Q一开始都是往右的Q找到第一个往左的p了)。后l则正好相反。证明可以用中序遍历?br /><2>找某个值v0的前和后Qgؓv0的结点在树中不一定存在)?br />所谓v0的前和后Q就是指在树中值小于(也有的是不大于)v0的最大的l点的|和树中值大于(也有的是不小于)v0的最的l点的倹{在有了操作Q?Q【不通过伸展操作N根结点的前趋和后l】以后,q个操作变得极ؓҎQ先q行普通的查找操作Q查扑րgؓv0的结点)Q如果能扑ֈQ则剩下的步骤就和操作(1Q一样了Q如果找不到Q则必然是找到某个空l点Q?Q处Q假讑֜q里插入一个gؓv0的结点(只是假设Q不是真插入Q,则该l点昄是没有左子结点的Q因此就?#8220;从该l点开始往上查找,直到扑ֈW一个是其父l点的右子结点的l点为止Q则q个l点的父l点是该结点的前趋”Q也是v0的前;后cM?br />在查找过E中可以q行一个常C化:讄i为查找过E中“双{”的最后一个结点(x到该l点后,接下来是该结点的叛_l点Q,每次往叛_l点转的时候就更新iQ则最后结点i是值v0的前;后cM?br /><3>删除所有值在某区间内的结点(q个区间可以是开区间、闭区间或半开半闭区间Q?br />以开区间ZQ删除树中所有值在(l, r)范围内的l点。先扑ֈl的前P和r的后lSQ注意这里的前趋和后l是包括“{于”的)Q然后将P伸展到根QS伸展到P的右子结点处Q则S的左子树中就是所有值在(l, r)范围内的l点Q直接删掉这子树即可(注意删除后要更新S和PQ;若改为闭区间Q则前和后中的“{于”LQ即必须是小于或大于Q;半开半闭区间则一半按开区间处理Q一半按闭区间处理。问题是Q如果点P或点S不存在怎么办。有两种解决办法Q一是若P和S之一存在Q则其伸展到根Q然后直接删掉其左子树或叛_树即可;若P和S都不存在Q则树ؓI,直接root|ؓ0卛_Q二是按照sequence的办法,加入两个边界l点Q当前趋或后l不存在时就认ؓ是边界结炏V?br />其实不光是删除,在找Cq棵子树后可以对它进行一些整体操作,从而让Splay TreehU段树的功能Q这个在下面的NOI2005 sequence那一题里面会ȝQ?br /><4>插入一|Q当然这|也是Splay TreeQƈ且原树中的结点值序列与新树中的l点值序列不怺Q?br />有时候,题目中会q箋出现很多插入操作Q中间没有其它操作,此时Q与其一个一个插入,q不如将它们先徏成一|Q徏树的Ҏ在下一里ȝQ,再整体插入。整体插入的ҎQ设L和R分别是新树里值最的l点和值最大的l点Q在原树中找到L的前P和R的后lSQ将P伸展到根QS伸展到P的右子结点处Q由于原树中的结点值序列与新树中的l点值序列不怺Q也是原树中的l点D么小于L的|要么大于R的|Q因此S无左子结点,此时新树作为S的左子树卛_?br /><img src ="http://www.shnenglu.com/MatoNo1/aggbug/149067.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-21 11:31 <a href="http://www.shnenglu.com/MatoNo1/archive/2011/06/21/149067.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>l于摘掉了不会^衡树的帽?/title><link>http://www.shnenglu.com/MatoNo1/archive/2011/06/18/148934.html</link><dc:creator>Mato_No1</dc:creator><author>Mato_No1</author><pubDate>Sat, 18 Jun 2011 13:21:00 GMT</pubDate><guid>http://www.shnenglu.com/MatoNo1/archive/2011/06/18/148934.html</guid><wfw:comment>http://www.shnenglu.com/MatoNo1/comments/148934.html</wfw:comment><comments>http://www.shnenglu.com/MatoNo1/archive/2011/06/18/148934.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.shnenglu.com/MatoNo1/comments/commentRss/148934.html</wfw:commentRss><trackback:ping>http://www.shnenglu.com/MatoNo1/services/trackbacks/148934.html</trackback:ping><description><![CDATA[     摘要: 今天真是有纪忉|义啊……以前试着捉了N遍的cashier今天竟然AC了,本沙茶终于掌握了q树!Q!【Splay Tree及其实现?lt;1>l点记录的信息:一般情况下Splay Tree是用U性存储器Q结构数l)来存储的Q可以避免在Linux下的指针异常问题。这样对于某个结点,臛_要记录以下的域:|又叫关键字)、左子结点的下标、右子结点的下标、父l点下标、子树大...  <a href='http://www.shnenglu.com/MatoNo1/archive/2011/06/18/148934.html'>阅读全文</a><img src ="http://www.shnenglu.com/MatoNo1/aggbug/148934.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-18 21:21 <a href="http://www.shnenglu.com/MatoNo1/archive/2011/06/18/148934.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss> <footer> <div class="friendship-link"> <p>лǵվܻԴȤ</p> <a href="http://www.shnenglu.com/" title="精品视频久久久久">精品视频久久久久</a> <div class="friend-links"> </div> </div> </footer> <a href="http://www.zhaodongjie.cn" target="_blank">AþþƷ</a>| <a href="http://www.agentsystem.cn" target="_blank">99þùѸ</a>| <a href="http://www.ccjump.cn" target="_blank">ƷþþþjkƷ</a>| <a href="http://www.lskcop.cn" target="_blank">þþþӰԺŮ</a>| <a href="http://www.soumee.com.cn" target="_blank">Ʒþùһ㽶</a>| <a href="http://www.lnsmgg.cn" target="_blank">þþþùƷ</a>| <a href="http://www.525work.cn" target="_blank">þùƷþþƷ</a>| <a href="http://www.pajiangxing.com.cn" target="_blank">߾þþƷĹ</a>| <a href="http://www.xitie520.cn" target="_blank">ݺɫþۺ</a>| <a href="http://www.sobseo.cn" target="_blank">պݺݾþ͵͵ɫۺ</a>| <a href="http://www.shbolangjixie.cn" target="_blank">þԭavapp </a>| <a href="http://www.icrms.org.cn" target="_blank">þҹɫƷ</a>| <a href="http://www.bjnyjdxcj.cn" target="_blank">ձƷþ</a>| <a href="http://www.lidonsj.cn" target="_blank">Ʒݾþþþ</a>| <a href="http://www.dfux.com.cn" target="_blank">þ޾ƷVA</a>| <a href="http://www.haiyunfu.cn" target="_blank">ϼþùƷӰԺ</a>| <a href="http://www.caikuaipeixun.com.cn" target="_blank">þþþþþþþþþþþ</a>| <a href="http://www.520menghuan.cn" target="_blank">ھƷ˾þþþӰԺ԰</a>| <a href="http://www.hongyunjp.cn" target="_blank">ۺϾþĻӰ</a>| <a href="http://www.85062.com.cn" target="_blank">þùֻоƷ</a>| <a href="http://www.cnmere.cn" target="_blank">99ƷȾþ</a>| <a href="http://www.huangjisoo.cn" target="_blank">ɫݺݾþAVۺ</a>| <a href="http://www.jddy.net.cn" target="_blank">޾Ʒרþͬ</a>| <a href="http://www.guwanwei.cn" target="_blank">99þùһ</a>| <a href="http://www.jiayubao.com.cn" target="_blank">ŷսþþþþþþ</a>| <a href="http://www.byrrj.cn" target="_blank">vĻþ 뾫ƷþɪӰ </a>| <a href="http://www.7788mm.cn" target="_blank">ٸþĻ</a>| <a href="http://www.hyattzhuzhou.cn" target="_blank">Ůaaaþþü</a>| <a href="http://www.qcwxfw.cn" target="_blank">˾þ91</a>| <a href="http://www.cqzmz.cn" target="_blank">Ʒ91þþþþþ</a>| <a href="http://www.ofjf.cn" target="_blank">պƷþĻ</a>| <a href="http://www.sxysw.cn" target="_blank">þۺϳDž</a>| <a href="http://www.dgcry.cn" target="_blank">޹ۺϾþ</a>| <a href="http://www.zzjiale.cn" target="_blank">þˬˬƬAV</a>| <a href="http://www.034867.cn" target="_blank">91Ʒɫ۾þ</a>| <a href="http://www.bjhswt.com.cn" target="_blank">һձȾþۺ</a>| <a href="http://www.wwwocj.com.cn" target="_blank">þ99Ʒһ </a>| <a href="http://www.369live.cn" target="_blank">ŷþþþ</a>| <a href="http://www.ydxxfw.cn" target="_blank">Ʒһþò</a>| <a href="http://www.34lz.cn" target="_blank">Ʒһþ</a>| <a href="http://www.gsasv.cn" target="_blank">ŷ޹Ʒþѿ</a>| <script> (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })(); </script> </body>