区间反转模板题
好像最后输出换行符会被判错(?)
#include <iostream>
#include <cstdio>
#include <stack>
#define N 200050
#define INF (1<<30)
using namespace std;
int siz[N],rev[N],s[N][2],a[N],fa[N],tr[N];
int ans[N],n,m,cnt,tot,rt;
inline void update(int t) { siz[t] = siz[ s[t][0] ] + siz[ s[t][1] ] + 1; }
inline void push_down(int t) {
if (!rev[t]) return ; rev[t] ^= 1;
swap(s[t][0],s[t][1]);
rev[ s[t][0] ] ^= 1; rev[ s[t][1] ] ^= 1;
}
void rot(int x,int &k) {
int y = fa[x] , z = fa[y] , l = (s[y][0] == x) ^ 1 , r = l ^ 1;
if (y == k) k = x; else {
if (y == s[z][0]) s[z][0] = x; else s[z][1] = x;
}
s[y][l] = s[x][r]; s[x][r] = y;
fa[y] = x; fa[x] = z; fa[ s[y][l] ] = y;
update(y); update(x);
}
stack<int> sta;
void SPlay(int x,int &k) {
while (x != k) {
int y = fa[x] , z = fa[y];
if (y != k) {
if ((s[z][0] == y) ^ (s[y][0] == x)) rot(x,k); else rot(y,k);
}
rot(x,k);
}
}
void build(int l,int r,int &t,int f) {
if (l > r) return ;
int mid = (l + r) >> 1;
tr[ t=++cnt ] = a[mid]; siz[t] = 1; fa[t] = f;
if (l == r) return ;
build(l,mid-1,s[t][0],t);
build(mid+1,r,s[t][1],t);
update(t);
}
void dfs(int t) {
push_down(t);
if (s[t][0]) dfs(s[t][0]);
ans[++tot] = tr[t];
if (s[t][1]) dfs(s[t][1]);
}
int kth(int k,int t) {
push_down(t);
int tmp = siz[ s[t][0] ] + 1;
if (k == tmp) return t;
return tmp > k ? kth(k,s[t][0]) : kth(k-tmp,s[t][1]);
}
void solve() {
scanf("%d%d",&n,&m);
for (int i=2;i<=n+1;i++) a[i] = i-1;
a[1] = INF; a[n+2] = INF;
build(1,n+2,rt,0);
while (m--) {
int l,r; scanf("%d%d",&l,&r);
int u = kth(l,rt);
int v = kth(r+2,rt);
SPlay(v,rt);
SPlay(u,s[v][0]);
rev[ s[u][1] ] ^= 1;
}
dfs(rt);
for (int i=2;i<=tot-1;i++) printf("%d ",ans[i]);
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("3223.txt","r",stdin);
#endif
solve();
//printf("\n");
return 0;
}
本文介绍了一种基于树状数组实现的区间反转算法,并通过具体代码展示了如何进行区间元素的翻转操作,同时提供了完整的C++代码实现,用于解决特定类型的数据结构问题。
1619

被折叠的 条评论
为什么被折叠?



