题目背景
这是一道经典的Splay模板题——文艺平衡树。
题目描述
您需要写一种数据结构(可参考题目标题),来维护一个有序数列,其中需要提供以下操作:翻转一个区间,例如原有序序列是5 4 3 2 1,翻转区间是[2,4]的话,结果是5 2 3 4 1
输入输出格式
输入格式:
第一行为n,m n表示初始序列有n个数,这个序列依次是(1,2, \cdots n-1,n)(1,2,?n−1,n) m表示翻转操作次数
接下来m行每行两个数 [l,r][l,r] 数据保证 1 \leq l \leq r \leq n1≤l≤r≤n
输出格式:
输出一行n个数字,表示原始序列经过m次变换后的结果
输入输出样例
输入样例#1: 复制
5 3 1 3 1 3 1 4
输出样例#1: 复制
4 3 2 1 5
说明
n, m \leq 100000n,m≤100000
FHQ无敌,
解决区间问题的时候按照$r$分成两个
再按照$l$分成两个
那么我们就得到了需要翻转的区间
然后愉快的打标记就好啦
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<ctime> 5 #include<cstdlib> 6 using namespace std; 7 #define ls T[now].ch[0] 8 #define rs T[now].ch[1] 9 const int MAXN=1e6+10; 10 inline char nc() 11 { 12 static char buf[MAXN],*p1=buf,*p2=buf; 13 return p1==p2&&(p2=(p1=buf)+fread(buf,1,MAXN,stdin),p1==p2)?EOF:*p1++; 14 } 15 inline int read() 16 { 17 char c=nc();int x=0,f=1; 18 while(c<‘0‘||c>‘9‘){if(c==‘-‘)f=-1;c=nc();} 19 while(c>=‘0‘&&c<=‘9‘){x=x*10+c-‘0‘,c=nc();} 20 return x*f; 21 } 22 struct node 23 { 24 int ch[2],val,siz,pri,mark; 25 }T[MAXN]; 26 int tot=0; 27 int x,y,z,root=0,n,m; 28 int newnode(int v) 29 { 30 T[++tot].siz=1; 31 T[tot].val=v; 32 T[tot].pri=rand(); 33 return tot; 34 } 35 void update(int now) 36 { 37 T[now].siz=T[ls].siz+T[rs].siz+1; 38 } 39 int Build(int l,int r) 40 { 41 if(l>r) return 0; 42 int mid=(l+r)>>1; 43 int now=newnode(mid-1); 44 ls=Build(l,mid-1); 45 rs=Build(mid+1,r); 46 update(now); 47 return now; 48 } 49 void pushdown(int now) 50 { 51 if(T[now].mark&&now) 52 { 53 swap(ls,rs); 54 if(ls) T[ls].mark^=1; 55 if(rs) T[rs].mark^=1; 56 T[now].mark=0; 57 } 58 } 59 void split(int now,int k,int &x,int &y) 60 { 61 if(!now) {x=y=0;return ;} 62 pushdown(now); 63 if(T[ls].siz<k) 64 x=now,split(rs,k-T[ls].siz-1,rs,y); 65 else 66 y=now,split(ls,k,x,ls); 67 update(now); 68 } 69 int merge(int x,int y) 70 { 71 if(!x||!y) return x+y; 72 pushdown(x);pushdown(y); 73 if(T[x].pri<T[y].pri) 74 { 75 T[x].ch[1]=merge(T[x].ch[1],y); 76 update(x); 77 return x; 78 } 79 else 80 { 81 T[y].ch[0]=merge(x,T[y].ch[0]); 82 update(y); 83 return y; 84 } 85 } 86 void dfs(int now) 87 { 88 pushdown(now); 89 if(T[now].ch[0]) dfs(T[now].ch[0]); 90 if(T[now].val>=1&&T[now].val<=n) printf("%d ",T[now].val); 91 if(T[now].ch[1]) dfs(T[now].ch[1]); 92 } 93 int main() 94 { 95 #ifdef WIN32 96 freopen("a.in","r",stdin); 97 #else 98 #endif 99 //srand((unsigned)time(NULL)); 100 n=read(),m=read(); 101 root=Build(1,n+2); 102 while(m--) 103 { 104 int l=read(),r=read(); 105 int a,b,c,d; 106 split(root,r+1,a,b); 107 split(a,l,c,d); 108 T[d].mark^=1; 109 root=merge( merge(c,d) ,b ); 110 } 111 dfs(root); 112 return 0; 113 }
时间: 2024-10-02 11:26:06