华师一附中OI组

 找回密码
 立即注册
搜索
热搜: 活动 交友 discuz
12
返回列表 发新帖
楼主: admin
打印 上一主题 下一主题

P2596 [ZJOI2006]书架

[复制链接]

738

主题

1485

帖子

5420

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
5420
11#
 楼主| 发表于 2020-4-13 20:57:32 | 只看该作者
剩下的这个插入我做了一个多小时,思路其实很简单,T==0的话不做任何操作,T==1的话把它和他的后继进行交换,T==-1的话和前驱进行交换。我在写的时候
  1. swap(a[x].val,a[q[S]].val);
  2. swap(q[a[x].val],q[S]);
复制代码

没有意识到错误,调了很长的时间。最后用了直观的方法,
  1.      cin>>S>>T;
  2.               int x;
  3.               if (T!=0)
  4.                     {
  5.                            if (T==-1)x=Pre(q[S]);
  6.                            if (T== 1)x=Suc(q[S]);
  7.                                     
  8.                            ///这两个交换我曾经搞糊涂了
  9.                            int v=a[x].val;
  10.                            swap(a[x].val,a[q[S]].val);
  11.                            swap(q[v],q[S]);
  12.                      }
复制代码


回复 支持 反对

使用道具 举报

738

主题

1485

帖子

5420

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
5420
12#
 楼主| 发表于 2020-4-13 21:01:35 | 只看该作者
最后奉上我的程序,前前后后3个多小时,丢人
  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. const int inf=99999999;
  4. const int N=80100;
  5. struct node
  6. {
  7.         int val,fa,s[2],sz;  ///s0s1左右儿子
  8. } a[N];
  9. int p[N],q[N],n,m, tot, root;
  10. void ArrayPr()   /// 调试监视使用
  11. {
  12.         cout<<endl<<"  i ";
  13.         for (int i=1; i<=tot; i++) cout<<setw(3)<<i;
  14.         cout<<endl<<"val ";
  15.         for (int i=1; i<=tot; i++) cout<<setw(3)<<a[i].val;
  16.         cout<<endl<<" s0 ";
  17.         for (int i=1; i<=tot; i++) cout<<setw(3)<<a[i].s[0];
  18.         cout<<endl<<" s1 ";
  19.         for (int i=1; i<=tot; i++) cout<<setw(3)<<a[i].s[1];
  20.         cout<<endl<<" sz ";
  21.         for (int i=1; i<=tot; i++) cout<<setw(3)<<a[i].sz;
  22.         cout<<endl<<" fa ";
  23.         for (int i=1; i<=tot; i++) cout<<setw(3)<<a[i].fa;
  24.         cout<<endl;
  25. }
  26. void BSTPr(int rt)   
  27. {
  28.         if (a[rt].s[0]>0)  BSTPr(a[rt].s[0]);
  29.         cout<<a[rt].val<<' ';
  30.         if (a[rt].s[1]>0)  BSTPr(a[rt].s[1]);
  31. }
  32. void pushup(int rt)  
  33. {
  34.         int l=a[rt].s[0], r=a[rt].s[1];
  35.         a[rt].sz=a[l].sz+a[r].sz+1;
  36. }
  37. int Son(int x)
  38. {
  39.         int y=a[x].fa;
  40.         return  a[y].s[1]==x;
  41. }
  42. void R(int x)
  43. {
  44.         int y=a[x].fa;
  45.         int z=a[y].fa;
  46.         int k=Son(x);
  47.         int v=a[x].s[k^1];
  48.         a[y].s[k]=v,a[v].fa=y;
  49.         a[z].s[Son(y)]=x,a[x].fa=z;
  50.         a[x].s[k^1]=y,a[y].fa=x;
  51.         pushup(y),pushup(x);
  52. }
  53. void Splay(int x,int rt=root)
  54. {
  55.         rt=a[rt].fa;
  56.         int y,z;
  57.         while(a[x].fa!=rt)
  58.                 {
  59.                         y=a[x].fa,z=a[y].fa;
  60.                         if(z!=rt)
  61.                                 if(Son(x)==Son(y))R(y);
  62.                                 else R(x);
  63.                         R(x);
  64.                 }
  65.         if(rt==0)root=x;
  66. }

  67. int Ask(int S)
  68. {
  69.         Splay(S,root);
  70.         int l=a[root].s[0];
  71.         return a[l].sz;
  72. }

  73. int Query(int rt, int S) ///在RT子树中找第S小
  74. {
  75.         int l=a[a[rt].s[0]].sz;  /// RT的左儿子下的个数
  76.         if(l+1==S) return a[rt].val;
  77.         if(l+1>S) return Query(a[rt].s[0], S); ///左儿子里去找
  78.         if(l+1<S) return Query(a[rt].s[1], S-(l+1));
  79. }
  80. void Top(int S)
  81. {
  82.         Splay(S,root);
  83.         int  x=root;
  84.         int l=a[x].s[0];
  85.         int r=a[x].s[1];///右儿子
  86.         if (r==0) a[x].s[1]=l;
  87.         else
  88.                 {

  89.                         int p=r;
  90.                         ///找最左节点
  91.                         while (a[p].s[0]>0) p=a[p].s[0];
  92.                         Splay(p,r);
  93.                         a[p].s[0]=l;
  94.                         a[l].fa=p;
  95.                         pushup(p);
  96.                 }
  97.         a[x].s[0]=0;
  98. }
  99. void Bottom(int S)
  100. {
  101.         Splay(S,root);
  102.         int x=root;
  103.         int l=a[x].s[0];
  104.         int r=a[x].s[1];
  105.         if (l==0) a[x].s[0]=r;
  106.         else
  107.                 {
  108.                         int p=l;
  109.                         while (a[p].s[1]>0) p=a[p].s[1];
  110.                         Splay(p,r);

  111.                         a[p].s[1]=r;
  112.                         a[r].fa=p;
  113.                         pushup(p);
  114.                 }
  115.         a[x].s[1]=0;
  116. }

  117. int Pre(int S)
  118. {
  119.         Splay(S,root);
  120.         int l=a[S].s[0], ans=0;
  121.         if (l==0) return 0;
  122.         int p=l;
  123.         while(a[p].s[1]>0) p=a[p].s[1];
  124.         return p;
  125. }
  126. int Suc(int S)
  127. {
  128.                 Splay(S,root);
  129.         int r=a[S].s[1];
  130.         if (r==0) return 0;
  131.         int p=r;
  132.         while(a[p].s[0]>0) p=a[p].s[0];
  133.         return p;
  134. }
  135. int Build(int l,int r) ///前n个数直接建个满二叉树
  136. {
  137.         if (l>r) return 0;
  138.         if (l==r)
  139.                 {
  140.                         a[l].val=p[l];
  141.                         a[l].s[0]=a[l].s[1]=0;
  142.                         a[l].sz=1;
  143.                         return l;
  144.                 }
  145.         int m=(l+r)/2;
  146.         a[m].val=p[m];
  147.         int L=a[m].s[0]=Build(l,m-1);
  148.         int R=a[m].s[1]=Build(m+1,r);
  149.         a[L].fa=a[R].fa=m;
  150.         a[m].sz=a[L].sz+a[R].sz+1;
  151.         return m;
  152. }
  153. int main()
  154. {
  155.         cin>>n>>m;
  156.         for (int x,i=1; i<=n; i++)
  157.                 {
  158.                         cin>>x;
  159.                         p[i]=x;
  160.                         q[x]=i;
  161.                 }
  162.         tot=n;
  163.         root=Build(1,n);
  164.         for (int i=1; i<=n; i++)cout<<q[i]<<' ';
  165.         cout<<endl;

  166.         ///初始建树完毕
  167.         string opt;
  168.         int S,T;
  169.         while(m--)
  170.                 {
  171.                         cin>>opt;
  172.                         if(opt=="Top")
  173.                                 {
  174.                                         cin>>S;
  175.                                         Top(q[S]);
  176.                                 }
  177.                         if(opt=="Bottom")
  178.                                 {
  179.                                         cin>>S;
  180.                                         Bottom(q[S]);
  181.                                 }
  182.                         if(opt=="Insert")
  183.                                 {
  184.                                         cin>>S>>T;
  185.                                         int x;
  186.                                         if (T==-1)x=Pre(q[S]);
  187.                                         if (T== 1)x=Suc(q[S]);
  188.                                         ///这两个交换我曾经搞糊涂了
  189.                                         swap(q[a[x].val],q[S]);
  190.                                         swap(a[x].val,a[q[S]].val);
  191.                                 }
  192.                         if(opt=="Ask")
  193.                                 {
  194.                                         cin>>S;
  195.                                         cout<<Ask(q[S])<<endl;
  196.                                 }
  197.                         if(opt=="Query")
  198.                                 {
  199.                                         cin>>S;
  200.                                         cout<<Query(root,S)<<endl;
  201.                                 }
  202.                 }

  203.         return 0;
  204. }
  205. /*
  206. 10 10
  207. 1 3 2 7 5 8 10 4 9 6
  208. Query 3
  209. Top 5
  210. Ask 6
  211. Bottom 3
  212. Ask 3
  213. Top 6
  214. Insert 4 -1
  215. Query 5
  216. Query 2
  217. Ask 2
  218. */
复制代码
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|Archiver|手机版|小黑屋|服务支持:DZ动力|华师一附中OI组  

GMT+8, 2024-11-2 06:40 , Processed in 0.206497 second(s), 22 queries .

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表