最大序列和小白逛公園做過
區間修改的優先順序高於區間翻轉的優先順序(之前有題01串翻轉)
序列維護平衡樹 平衡樹維護的是下標 因此中序遍歷就是原序列
每個結點維護的都是結點 不像線段樹可以維護區間 所以build 的操作有一些不一樣
這題還卡空間 所以要弄乙個簡單的**操作
注意up的順序 必須從下到上 因為這個wa了好久
非常好(難調)的平衡樹題
#includeusingview codenamespace
std;
//input by bxd
#define rep(i,a,b) for(int i=(a);i<=(b);i++)
#define repp(i,a,b) for(int i=(a);i>=(b);--i)
#define ll long long
#define see(x) (cerr<
#define inf 0x3f3f3f3f
#define clr(a,v) memset(a,v,sizeof a)typedef pair
pii;
/////////////////////////////////
/const
int n=2e6+10
;queue
q;int lmax[n],rmax[n],siz[n],son[n][2
],id[n],sum[n],maxans[n],fa[n],lson,rson,col[n],rev[n],root,v[n],ncnt,a[n],m,n;
int chk(int
x)void up(int
pos)
void down(int
pos)
else
}if(rev[pos])
}void rotate(int
x)void splay(int x,int goal=0
) rotate(x);
}if(!goal)root=x;
}int find1(int x,int
k)void recycle(int
x)int split(int k,int
tot)
int qsum(int k,int
tot)
void upsum(int k,int tot,int
val)
void rever(int k,int
tot)
}void del(int k,int
tot)
void build(int l,int r,int
f)
if(l1
,mid);
if(r>mid)build(mid+1
,r,mid);
v[now]=a[mid];fa[now]=pre;
up(now);son[pre][mid>=f]=now;
}void insert(int k,int
tot)
build(
1,tot,0
);
int z=id[(1+tot)>>1
];
int x=find1(root,k+1),y=find1(root,k+2
); splay(x);splay(y,x);
fa[z]=y;son[y][0]=z;
up(y);up(x);
}int
main()
if(ch[0]=='r'
)rever(k,tot);
if(ch[0]=='
g')printf("
%d\n
",qsum(k,tot));
}return0;
}
P2042 NOI2005 維護數列
超級噁心的pushdown 昏天黑地的調 讓我想起了我那前幾個月的線段樹2 這噁心的一道題終於過了 太多錯誤,簡直說不過來 pushup pushdown 主要就是這倆不太清晰,亂pushdown 其他的寫的還沒啥毛病 能看出來 include include include include inc...
P2042 NOI2005 維護數列
這道題看到什麼維護序列的,肯定就是用資料結構的。這個東西叫你做下面的事情 首先確定用什麼資料結構。看到翻轉,二話不說就用splay。第乙個操作 在第posi位後加入tot個數字。我們就把這一段數字建出乙個子splay。用類似線段樹的建樹方式解決掉,比乙個乙個加入的建樹方式快,常數小。然後split出...
洛谷 P2042 NOI2005 維護數列
一直在想要做這道題,但是被那個碩大的splay標籤壓垮了 好了,切入正題 這道題應該是我第二次用splay來維護區間問題 我還是太菜了qaq 其實思路也很簡單,就是以每乙個位置的下標來進行維護,然後其實就是跟權值樹是一模一樣的了 然後再具體說一下 為了保證效率,像線段樹和文藝平衡樹一樣,我們可以維護...