洛谷 P3391文艺平衡树 【fhq_treap】
洛谷 P3391文艺平衡树
题意见链接。。。
题目明确说 splay模板题,我还是用了 fhq_treap(非旋treap)
对于此题来说,操作分为这么几块:
1、新加入节点,合并到基树中。
(要记录 size,val,pio(优先级,rand一下))
2、读入操作,开始翻转:
因为翻转的是区间,所以我们先把树按 r 分成两部分,然后再把左子树按 l-1 分成两部分,对应的需要操作的区间就是右子树。
用懒标记搞一下,再合并回去。
3、分离与合并操作:
分离:递归,如果 k 大于 size[left],那么就把左子树保留不变,递归右子树;左子树由 rt领头,右子树另到右子树中找节点。反之则同样。
合并:按优先级比较,pri[x]<pri[y] 则 x 的左子树保留,用 x 的右子树去和 y 合并。反之则用 y 的左子树和 x 合并。
4、上合与下传:
由于懒标记,所以要 pushdown,本题因为区间翻转,只需要记录被翻转几次,两次等于没有,抵消。
Pushup 也是线段树常规操作,更新完数据新的信息要上传到父亲节点更新。
总的来说就这样吧,待填坑。
贴代码:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 // 文艺平衡树 fhp_Treap 2 // By YoungNeal 3 #include<ctime> 4 #include<cstdio> 5 #include<cstdlib> 6 #define N 100005 7 8 int Root; 9 int lazy[N]; 10 int n,m,cnt; 11 int val[N],sze[N]; 12 int ch[N][2],prio[N]; 13 14 void pushup(int o){ 15 sze[o]=sze[ch[o][0]]+sze[ch[o][1]]+1; 16 } 17 18 void pushdown(int o){ 19 if(!lazy[o] or !o) return; 20 ch[o][0]^=ch[o][1]^=ch[o][0]^=ch[o][1]; 21 lazy[ch[o][0]]^=1; 22 lazy[ch[o][1]]^=1; 23 lazy[o]=0; 24 } 25 26 void split(int o,int k,int &x,int &y){ 27 if(!o) x=y=0; 28 else{ 29 pushdown(o); 30 if(k>sze[ch[o][0]]) x=o,split(ch[o][1],k-sze[ch[o][0]]-1,ch[o][1],y); 31 else y=o,split(ch[o][0],k,x,ch[o][0]); 32 pushup(o); 33 } 34 } 35 36 int merge(int x,int y){ 37 if(!x or !y) return x+y; 38 pushdown(x); pushdown(y); 39 if(prio[x]<prio[y]){ 40 ch[x][1]=merge(ch[x][1],y); 41 pushup(x); 42 return x; 43 } 44 else{ 45 ch[y][0]=merge(x,ch[y][0]); 46 pushup(y); 47 return y; 48 } 49 } 50 51 int newnode(int v){ 52 val[++cnt]=v; 53 sze[cnt]=1; 54 prio[cnt]=rand(); 55 return cnt; 56 } 57 58 void res(int l,int r){ 59 int a,b,c,d; 60 split(Root,r,a,b); 61 split(a,l-1,c,d); 62 lazy[d]^=1; 63 Root=merge(merge(c,d),b); 64 } 65 66 void dfs(int now){ 67 if(!now) return; 68 pushdown(now); 69 dfs(ch[now][0]); 70 printf("%d ",val[now]); 71 dfs(ch[now][1]); 72 } 73 74 signed main(){ 75 srand(time(0)); 76 scanf("%d%d",&n,&m); 77 for(int i=1;i<=n;i++) 78 Root=merge(Root,newnode(i)); 79 //printf("Root=%d\n",Root); 80 for(int x,y,i=1;i<=m;i++){ 81 scanf("%d%d",&x,&y); 82 res(x,y); 83 //printf("i=%d\n",i); 84 //dfs(Root); 85 } 86 //printf("Root=%d\n",Root); 87 dfs(Root); 88 return 0; 89 }
fightin fighting fighting