代码库.docx

上传人:b****5 文档编号:4100269 上传时间:2022-11-27 格式:DOCX 页数:243 大小:129.50KB
下载 相关 举报
代码库.docx_第1页
第1页 / 共243页
代码库.docx_第2页
第2页 / 共243页
代码库.docx_第3页
第3页 / 共243页
代码库.docx_第4页
第4页 / 共243页
代码库.docx_第5页
第5页 / 共243页
点击查看更多>>
下载资源
资源描述

代码库.docx

《代码库.docx》由会员分享,可在线阅读,更多相关《代码库.docx(243页珍藏版)》请在冰豆网上搜索。

代码库.docx

代码库

伸展树

Asimpleproblemwithintegers

//POJ-3468Asimpleproblemwithintegers

//YouhaveNintegers,A1,A2,...,AN.Youneedtodealwithtwokindsofoperations.Onetypeofoperationistoaddsomegivennumbertoeachnumberinagiveninterval.Theotheristoaskforthesumofnumbersinagiveninterval.

//"Cabc"meansaddingctoeachofAa,Aa+1,...,Ab.-10000≤c≤10000.

//"Qab"meansqueryingthesumofAa,Aa+1,...,Ab.

//Hint:

Thesumsmayexceedtherangeof32-bitintegers.

#defineSIZE100010//树的容量

typedefinttype;//V的类型

#definekey(CH[CH[r][1]][0])//关键树

//--------------------------下面开始节点域声明-----------------------------

////////////////////////////

intCH[SIZE][2],P[SIZE];//0左1右、父

typeV[SIZE];//值

intlen;//资源使用量

////////////////////////////

intCNT[SIZE];//本棵树的节点个数

////////////////////////////

intADD[SIZE];//标记-是否加上ADD

longlongSUM[SIZE];//本树中最小的值

////////////////////////////

////////////////////////////

//--------------------------下面开始操作节点-------------------------------

intnewNode(){//新建一个节点(先从回收站里找)

returnlen++;

}

voidinitNode(intx,typev,intch0,intch1,intp){//初始化每个节点

V[x]=v;

CH[x][0]=ch0;

CH[x][1]=ch1;

P[x]=p;

CNT[x]=1;

SUM[x]=V[x]=v;

ADD[x]=0;

}

//--------------------------下面开始操作伸展树----------------------------

voidinitTree(){//只需掉一次,清资源,设NULL节点

len=1;//从1开始,0代表NULL

initNode(0,0,0,0,0);

CNT[0]=0;

}

structSplayTree{

intr;//根

//--------------------------下面是基本函数---------------------------

SplayTree(typelv,typerv){//创建一个带哨兵的空SplayTree,lv/rv赋值成任何其实无所谓

inta=newNode();

intb=newNode();

initNode(a,lv,0,b,0);

initNode(b,rv,0,0,a);

push_up(b);push_up(a);

r=a;

}

voidrotate(intx,boolc){//将节点i,c=0左旋转zag,c=1右旋转zig

inty=P[x];

push_down(CH[x][0]);

push_down(CH[x][1]);

push_down(CH[y][c]);

CH[y][!

c]=CH[x][c];

if(CH[x][c])P[CH[x][c]]=y;

CH[x][c]=y;

P[x]=P[y];

P[y]=x;

if(P[x])CH[P[x]][CH[P[x]][1]==y]=x;

elser=x;

push_up(y);

}

voidsplay(intx,intf=0){//表示把结点x转到结点f的下面,默认为节点x成为根

inty;

boolb1,b2;

push_down(x);

while((y=P[x])!

=f){//用到了P[0]=0来处理x=0的情况

if(P[y]==f){

rotate(x,CH[y][0]==x);

}else{

b1=(y==CH[P[y]][0]);

b2=(x==CH[y][0]);

rotate((b1^b2)?

x:

y,b2);

rotate(x,b1);

}

}

push_up(x);

}

//选择第rank个节点,并且将这个节点splay到f下面,从0开始

voidselect(intrank,intf=0){

if(rank>=CNT[r]||rank<0)return;

inti=r;

while(true){

push_down(i);

if(CNT[CH[i][0]]==rank)break;

if(CNT[CH[i][0]]>rank){

i=CH[i][0];

}else{

rank-=CNT[CH[i][0]]+1;

i=CH[i][1];

}

}

splay(i,f);

}

voidinterval(intbegin,intend){//选中[begin,end)左闭右开的区间

select(begin-1);

select(end,r);

}

//--------------------下面开始insert和remove----------------------

voidinsert(type*arr,intn){//在root后面插入arr(似满二叉树),assumen>0!

intx=newNode();

initNode(x,arr[n-1],insertDfs(arr,n-1,x),CH[r][1],r);

if(CH[x][1])P[CH[x][1]]=x;

CH[r][1]=x;

splay(x);

}

intinsertDfs(type*arr,intn,intfather){

if(n<=0)return0;

intidx=n/2;

intx=newNode();

initNode(x,arr[idx],insertDfs(arr,idx,x),insertDfs(arr+idx+1,n-idx-1,x),father);

push_up(x);

returnx;

}

//--------------------下面开始push----------------------

voidpush_up(intidx){

if(!

idx)return;

//断言此处idx没有任何标记!

CNT[idx]=CNT[CH[idx][0]]+CNT[CH[idx][1]]+1;

SUM[idx]=SUM[CH[idx][0]]+SUM[CH[idx][1]]+V[idx];

}

voidpush_down(intidx){

if(!

idx)return;

if(ADD[idx]){

if(CH[idx][0])ADD[CH[idx][0]]+=ADD[idx];

if(CH[idx][1])ADD[CH[idx][1]]+=ADD[idx];

V[idx]+=ADD[idx];

SUM[idx]+=(longlong)ADD[idx]*CNT[idx];

ADD[idx]=0;

}

}

//------------------------一些其他函数-------------------

voidaddKeyTree(intv){//将关键树每个节点都加上v

if(!

key)return;

ADD[key]+=v;

splay(key);

}

//-----------------------打印函数--------------------

voidoutputKeySUM(){

printf("%lld\n",SUM[key]);

}

};

intarr[SIZE];

intmain(){

intn,q;

inta,b,d;

charc;

while(scanf("%d%d",&n,&q)!

=EOF){

for(inti=0;i

initTree();

SplayTreesp(0,0);

sp.insert(arr,n);

while(q--){

scanf("%c%d%d",&c,&a,&b);

if(c=='Q'){

sp.interval(a,b+1);

sp.outputKeySUM();

}else{

scanf("%d",&d);

sp.interval(a,b+1);

sp.addKeyTree(d);

}

}

}

return0;

}

GSS6

/**

SPOJ-4487CanyouanswerthesequeriesVI

Ixy:

insertelementyatpositionx(betweenx-1andx).

Dx:

deletetheelementatpositionx.

Rxy:

replaceelementatpositionxwithy.

Qxy:

printmax{Ai+Ai+1+..+Aj|x<=i<=j<=y}.

*/

#defineSIZE200010//树的容量

typedefinttype;//V的类型

constintinf=10010;//inf

#definekey(CH[CH[r][1]][0])//关键树

//--------------------------下面开始节点域声明-----------------------------

////////////////////////////

intCH[SIZE][2],P[SIZE];//0左1右、父

typeV[SIZE];//值

intlen;//资源使用量

////////////////////////////

intCNT[SIZE];//本棵树的节点个数

////////////////////////////

intSUM[SIZE];//本树V的和

intLL[SIZE],RR[SIZE],MM[SIZE];//从左面连续的值的和,右面连续的值的和,连续的最大值的和

//--------------------------下面开始操作节点-------------------------------

intnewNode(){//新建一个节点(先从回收站里找)

returnlen++;

}

voidinitNode(intx,typev,intch0,intch1,intp){//初始化每个节点

V[x]=v;

CH[x][0]=ch0;

CH[x][1]=ch1;

P[x]=p;

CNT[x]=1;

SUM[x]=V[x];

MM[x]=LL[x]=RR[x]=V[x];

}

//--------------------------下面开始操作伸展树----------------------------

voidinitTree(){//只需掉一次,清资源,设NULL节点

len=1;//从1开始,0代表NULL

initNode(0,-inf,0,0,0);

CNT[0]=SUM[0]=0;

}

structSplayTree{

intr;//根

//--------------------------下面是基本函数---------------------------

SplayTree(typelv,typerv){//创建一个带哨兵的空SplayTree,lv/rv赋值成任何其实无所谓

inta=newNode();

intb=newNode();

initNode(a,lv,0,b,0);

initNode(b,rv,0,0,a);

push_up(b);push_up(a);

r=a;

}

voidrotate(intx,boolc){//将节点i,c=0左旋转zag,c=1右旋转zig

inty=P[x];

CH[y][!

c]=CH[x][c];

if(CH[x][c])P[CH[x][c]]=y;

CH[x][c]=y;

P[x]=P[y];

P[y]=x;

if(P[x])CH[P[x]][CH[P[x]][1]==y]=x;

elser=x;

push_up(y);

}

voidsplay(intx,intf=0){//表示把结点x转到结点f的下面,默认为节点x成为根

inty;

boolb1,b2;

while((y=P[x])!

=f){//用到了P[0]=0来处理x=0的情况

if(P[y]==f){

rotate(x,CH[y][0]==x);

}else{

b1=(y==CH[P[y]][0]);

b2=(x==CH[y][0]);

rotate((b1^b2)?

x:

y,b2);

rotate(x,b1);

}

}

push_up(x);

}

//选择第rank个节点,并且将这个节点splay到f下面,从0开始

voidselect(intrank,intf=0){

if(rank>=CNT[r]||rank<0)return;

inti=r;

while(true){

if(CNT[CH[i][0]]==rank)break;

if(CNT[CH[i][0]]>rank){

i=CH[i][0];

}else{

rank-=CNT[CH[i][0]]+1;

i=CH[i][1];

}

}

splay(i,f);

}

voidinterval(intbegin,intend){//选中[begin,end)左闭右开的区间

select(begin-1);

select(end,r);

}

//--------------------下面开始insert和remove----------------------

voidinsert(type*arr,intn){//在root后面插入arr(似满二叉树),assumen>0!

intx=newNode();

initNode(x,arr[n-1],insertDfs(arr,n-1,x),CH[r][1],r);

if(CH[x][1])P[CH[x][1]]=x;

CH[r][1]=x;

splay(x);

}

intinsertDfs(type*arr,intn,intfather){

if(n<=0)return0;

intidx=n/2;

intx=newNode();

initNode(x,arr[idx],insertDfs(arr,idx,x),insertDfs(arr+idx+1,n-idx-1,x),father);

push_up(x);

returnx;

}

intcutKeyTree(){//切断keyTree和父亲的联系而已,不将节点清除回收,并返回keyTree

if(!

key)return0;

intres=key;

key=P[res]=0;//清除

splay(CH[r][1]);

returnres;

}

//--------------------下面开始push----------------------

voidpush_up(intidx){

if(!

idx)return;

//断言此处idx没有任何标记!

CNT[idx]=CNT[CH[idx][0]]+CNT[CH[idx][1]]+1;

SUM[idx]=SUM[CH[idx][0]]+SUM[CH[idx][1]]+V[idx];//[]

LL[idx]=max(LL[CH[idx][0]],SUM[CH[idx][0]]+V[idx]+max(LL[CH[idx][1]],0));

RR[idx]=max(RR[CH[idx][1]],SUM[CH[idx][1]]+V[idx]+max(RR[CH[idx][0]],0));

MM[idx]=max(MM[CH[idx][0]],MM[CH[idx][1]]);

MM[idx]=max(MM[idx],V[idx]+max(0,RR[CH[idx][0]])+max(0,LL[CH[idx][1]]));

}

//------------------------一些其他函数-------------------

voidreplaceKeyTree(intv){

//assumeCNT[key]=1

V[key]=v;

splay(key);

}

//------------------以下是打印代码------------------------

voidoutputKeyMM(){

printf("%d\n",MM[key]);

}

};

intarr[SIZE];

intms(){

charc;

boolfu=false;

while(c=getchar(),c>'9'||c<'0')if(c=='-')fu=true;

intres;

for(res=c-'0';c=getchar(),c>='0'&&c<='9';res=res*10+c-'0');

if(fu)res=-res;

returnres;

}

intmain(){

intn,q,a,b;

charc;

n=ms();

initTree();

SplayTreesp(0,0);

for(inti=0;i

sp.insert(arr,n);

q=ms();

while(q--){

while(c=getchar(),c>'Z'||c<'A');

if(c=='I'){

a=ms();b=ms();

sp.select(a-1);

sp.insert(&b,1);

}elseif(c=='D'){

a=ms();

sp.interval(a,a+1);

sp.cutKeyTree();

}elseif(c=='R'){

a=ms();b=ms();

sp.interval(a,a+1);

sp.replaceKeyTree(b);

}elseif(c=='Q'){

a=ms();b=ms();

sp.interval(a,b+1);

sp.outputKeyMM();

}elsewhile

(1);

}

return0;

}

GSS6_WHU

constintmaxq=100000+2000;

constintmaxn=100000+maxq;

structnode{

intval,size;

intsum,ml,mr,mc;

node*ch[2],*pre;

}*null,*root,*S[maxn],data[maxn];

inttot,top,tmp[maxq];

inlinenode*New_Node(intx){

node*p;

if(top)

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 外语学习 > 其它语言学习

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1