【以前的空间】几道平衡树

vijos 1459 车展

一个空的树.. 依次添加1到n。就能解决左端点为1的所有询问了吧。然后从2开始做一遍啊...n方logn得到全部答案。”神牛的话就是这么吊……看上去没什么信息量但还是水很深……实际上要维护子树内元素和。也就是我程序里面写的change,lsum指左子树中所有点的值得和,rsum指右子树中所有点的值得和,zsum指整个子树中节点的和,也就是lsum+rsum+本节点的值。在计算代价的时候是这样的……假设从i加到j需到的代价为sum,首先找到中间值,就是排名为(j-i)div2+1的点l,然后在sum上加上“这个节点左子树上的点的总和与这个节点的值*左子树节点个数的绝对值”,由于后者要比前者大……所以就是key[l]*s[left[l]]。右子树就是反过来。但是sum的值还不止这些,还需要在递归的时候加上一些值,即如果这个点是左儿子,那sum就要加上他爹和他右兄弟上所有点的值与他爹和他右兄弟上所有点数*这个key[l]的值,就是rsum[t]+key[t]-(s[right[t]]+1)*l,如果是右子树也是一样……这样就没了。最后注意,一定要开int64,因为这个错误,wa了3次……

const maxn=4000;

var key,s,left,right,a:array[0..maxn] of longint;

    lsum,rsum,zsum:array[0..maxn]of int64;
    tt,i,j,k,l,n,m,t:longint;
    f:array[0..2000,0..2000]of int64;
    sum:int64;

procedure change(t:longint);

begin

  lsum[t]:=zsum[left[t]];
  rsum[t]:=zsum[right[t]];
  zsum[t]:=lsum[t]+rsum[t]+key[t];

end;

procedure right_rotate(var t:longint);

var

  k:longint;

begin

   k:=left[t];
   left[t]:=right[k];
   right[k]:=t;
   s[k]:=s[t];
   s[t]:=s[left[t]]+s[right[t]]+1;
   change(t);
   change(k);
   t:=k;

end;

procedure left_rotate(var t:longint);

var

  k:longint;

begin

   k:=right[t];
   right[t]:=left[k];
   left[k]:=t;
   s[k]:=s[t];
   s[t]:=s[left[t]]+s[right[t]]+1;
   change(t);
   change(k);
   t:=k;

end;

procedure maintain(var t:longint;flag:boolean);

begin

if flag=false then
      if s[left[left[t]]]>s[right[t]] then
         right_rotate(t)
      else
         if s[right[left[t]]]>s[right[t]] then begin
            left_rotate(left[t]);
            right_rotate(t);
         end
         else
            exit   else
      if s[right[right[t]]]>s[left[t]] then
         left_rotate(t)
      else
         if s[left[right[t]]]>s[left[t]] then begin
            right_rotate(right[t]);
            left_rotate(t);
         end
         else
            exit;
   maintain(left[t],false);
   maintain(right[t],true);
   maintain(t,true);
maintain(t,false);

end;

procedure insert(var t,v:longint);

begin

if t=0 then begin
      inc(tt);
      t:=tt;
      key[t]:=v;
      s[t]:=1;
      left[t]:=0;
      right[t]:=0;
      lsum[t]:=0;
      rsum[t]:=0;
      zsum[t]:=key[t];
   end
   else begin
      inc(s[t]);
      if v<key[t] then begin
         insert(left[t],v);
         inc(lsum[t],v);
         inc(zsum[t],v);
      end
      else begin
         insert(right[t],v);
         inc(rsum[t],v);
         inc(zsum[t],v);
      end;
      maintain(t,v>=key[t]);
end;

end;

function select(var t:longint;k:longint):longint;

var

  l:longint;

begin

if k=s[left[t]]+1 then begin
      l:=key[t];
      sum:=s[left[t]]*l-lsum[t]+rsum[t]-s[right[t]]*l;
      exit(key[t]);
   end else
   if k<=s[left[t]] then begin
      l:=select(left[t],k);
      sum:=sum+rsum[t]+key[t]-(s[right[t]]+1)*l;
      exit(l)
   end
   else begin
      l:=select(right[t],k-1-s[left[t]]);
     sum:=sum+(s[left[t]]+1)*l-key[t]-lsum[t];
     exit(l);
end;

end;

begin

readln(n,m);

for i:=1 to n do
    read(a[i]);
  for i:=1 to n do
    f[i,i]:=0;
  for i:=1 to n-1 do begin
    fillchar(left,sizeof(left),0);
    fillchar(s,sizeof(s),0);
    fillchar(right,sizeof(right),0);
    fillchar(lsum,sizeof(lsum),0);
    fillchar(rsum,sizeof(rsum),0);
    fillchar(zsum,sizeof(zsum),0);
    fillchar(key,sizeof(key),0);   //傻逼又没有必要的初始化,去掉也行啦……
    tt:=0;
    t:=0;
    insert(t,a[i]);
    for j:=i+1 to n do begin
      insert(t,a[j]);
      sum:=0;
      k:=select(t,(j-i)div 2+1);
      f[i,j]:=sum;
    end;
  end;
  sum:=0;
  for i:=1 to m do
    begin
      readln(j,k);
      sum:=sum+f[j,k];
    end;
writeln(sum);

end.

vijos 1647 不差钱

var
  ans,tot,i,n,p,t:longint;
  s,left,right,key,value:array[0..101000]of longint;
  a:array[0..1000010]of longint;
  m:int64;

procedureleftrotate(var t:longint);
var
  k:longint;
begin
  k:=right[t];
  right[t]:=left[k];
  left[k]:=t;
  s[k]:=s[t];
  s[t]:=s[left[t]]+s[right[t]]+1;
  t:=k;
end;

procedurerightrotate(var t:longint);
var
  k:longint;
begin
  k:=left[t];
  left[t]:=right[k];
  right[k]:=t;
  s[k]:=s[t];
  s[t]:=s[left[t]]+s[right[t]]+1;
  t:=k;
end;

proceduremaintain(var t:longint);
begin
  if s[left[left[t]]]>s[right[t]] then begin
    rightrotate(t);
    maintain(right[t]);
    maintain(t);
    exit;
  end;
  if s[right[left[t]]]>s[right[t]] then begin
    leftrotate(left[t]);
    rightrotate(t);
    maintain(left[t]);
    maintain(right[t]);
    maintain(t);
    exit;
  end;
  if s[right[right[t]]]>s[left[t]] then begin
    leftrotate(t);
    maintain(left[t]);
    maintain(t);
    exit;
  end;
  if s[left[right[t]]]>s[left[t]] then begin
    rightrotate(right[t]);
    leftrotate(t);
    maintain(left[t]);
    maintain(right[t]);
    maintain(t);
  end;
end;

procedureinsert(var t:longint;v:longint);
begin
  if t=0 then begin
    inc(tot);
    t:=tot;
    s[tot]:=1;
    left[tot]:=0;
    right[tot]:=0;
    key[tot]:=v;
    value[ans]:=v;
  end
  else begin
    s[t]:=s[t]+1;
    if v<=key[t] then
      insert(left[t],v)
    elseinsert(right[t],v);
    maintain(t);
  end;
end;

functionselect(var t:longint;k:longint):longint;
var
  l:longint;
begin
  if k=s[left[t]]+1 then
    select:=key[t]
  else begin
    if k<=s[left[t]] then
      select:=select(left[t],k)
    else select:=select(right[t],k-1-s[left[t]]);
  end;
end;

begin
  readln(m);
  t:=0;
  tot:=0;
  ans:=0;
  fillchar(a,sizeof(a),0);
  read(p);
  while p<>0 do begin
    read(n);
    case p of
      1:begin
        inc(ans);
        insert(t,n);
        inc(a[n]);
        end;
      2:dec(a[value[n]]);
      3:begin
        i:=select(t,ans-n+1);
        if i>m then writeln(‘Dui bu qi,Mei you.‘)
        else
          if a[i]>0 then writeln(‘You. ‘,i,‘ Yuan.‘)
          else writeln(‘Mei you. Zhe ge ke yi you. Zhe ge zhen mei you!‘)
      end;
    end;
    read(p);
  end;
end.

时间: 2024-10-27 03:35:13

【以前的空间】几道平衡树的相关文章

平衡树讲解(旋转treap,非旋转treap,splay)

在刷了许多道平衡树的题之后,对平衡树有了较为深入的理解,在这里和大家分享一下,希望对大家学习平衡树能有帮助. 平衡树有好多种,比如treap,splay,红黑树,STL中的set.在这里只介绍几种常用的:treap和splay(其中treap包括旋转treap和非旋转treap). 一.treap treap这个词是由tree和heap组合而成,意思是树上的的堆(其实就是字面意思啦qwq).treap可以说是由二叉搜索树(BST)进化而来,二叉搜索树每个点满足它左子树中所有点权值都比它小,它右子

[BZOJ 1112] [POI2008] 砖块Klo 【区间K大】

题目链接:BZOJ - 1112 题目分析 枚举每一个长度为k的连续区间,求出这个区间的最优答案,更新全局答案. 可以发现,这个区间的所有柱子最终都变成这k个数的中位数时最优,那么我们就需要查询这个区间的中位数了. 找到中位数之后,我们还应该求出这个区间内小于中位数的数的和,大于中位数的数的和,从而求出操作步数. 这些需要求的值可以用线段树或平衡树来写,我写的是线段树,但是实际上这是一道POI的题目,在MAIN上的空间限制只有35MB,线段树应该是不行的. 因为平衡树只需要 O(n) 空间,所以

[洛谷1533] 可怜的狗狗

题目背景 小卡由于公务需要出差,将新家中的狗狗们托付给朋友嘉嘉,但是嘉嘉是一个很懒的人,他才没那么多时间帮小卡喂狗狗. 题目描述 小卡家有N只狗,由于品种.年龄不同,每一只狗都有一个不同的漂亮值.漂亮值与漂亮的程度成反比(漂亮值越低越漂亮),吃饭时,狗狗们会按顺序站成一排等着主人给食物. 可是嘉嘉真的很懒,他才不肯喂这么多狗呢,这多浪费时间啊,于是他每次就只给第i只到第j只狗中第k漂亮的狗狗喂食(好狠心的人啊).而且为了保证某一只狗狗不会被喂太多次,他喂的每个区间(i,j)不互相包含. 输入输出

[并查集]JZOJ 5794 旅行

Description 悠悠岁月,不知不觉,距那传说中的pppfish晋级泡泡帝已是过 去数十年.数十年 中,这颗泡泡树上,也是再度变得精彩,各种泡泡 天才辈出,惊艳世人,然而,似乎 不论后人如何的出彩,在他们的头 顶之上,依然是有着一道身影而立. 泡泡帝,pppfish. 现在,pppfish即将带着被自己收服的无数个泡泡怪前往下一个 空间,而在前往下 一个空间的道路上,有N个中转站,和M条空间虫洞连接中转站(双向通道,可有重 边,可有环),然而,通过虫洞 是要一定的条件的,pppfish将手

《学习之道》第十章空间宫殿

要你回想一个你熟悉的空间,然后把它当成视觉形象的记事本,用来存储你想要记住的概念形象. 比如你购物单上的物品(牛奶.面包.鸡蛋),你可以想象门前有一大瓶牛奶,面部掉在沙发上,破鸡蛋的蛋清从咖啡桌边一滴滴流下来. 就是你走过一个非常熟悉的地点,里面有你想要记住的东西. 初次尝试记忆宫殿法,会记得没那么快.在脑中构思出具体图像还是要费劲的.但是你会逐渐熟能生巧.一项调查显示,会用记忆宫殿法的人,在想象中把物体放置在当地大学的各个角落,在心中把这过程“走”上一两遍,它就能记住含有四五十件物品的清单上9

《学习之道》第十章视觉和空间记忆的原因

那些后来的记忆高手,都说老套的形象记忆法能让他们记得更快更轻松. 无论是助记图像.顺口溜.还是假想的“宫殿”,它们之所以会管用,是因为能在你要开小差时帮你集中注意力. 就算起初你编造的字面含义十分可笑,但它们也能让你注意到意义对记忆的重要性. 简言之,记忆法让你平时的学习更有意义.印象更深,也更有趣味.这也是形象记忆的原因吧,有有趣! 原文地址:https://www.cnblogs.com/158-186/p/10923527.html

腾讯、网易有道和阿里的笔试分享及自我总结

声明:本人Android移动开发岗 腾讯:考的很杂 选择题(25题不定项):考的包括: 编译原理两题, 计算机网络一两题(私网地址), C++若干, IOS开发一两题, 还有二叉树两三题,先后序遍历,求深度 jvm也有一题, 概率论一两题, JavaScript一题, 还有C语言(包括指针数组,数组指针,指针函数之类的)也挺多的 更多的是看程序求输出. 大题: 1,10亿QQ号用Set和Vector两个容器来删除奇数号 2,猴子摘香蕉,一次可以摘一根或两根,求摘50根有几种摘法(斐波那契数列)

怎么用HD Tune检测硬盘坏道

HD Tune软件不仅小巧而且很易使用,是一款检测电脑硬盘的优良工具.不仅是电脑硬盘,包括移动硬盘在内一样可以检测.那么,如何使用HD Tune呢?如何使用HD Tune检测磁盘坏道呢? 工具/原料 HD Tune软件一枚 使用HD Tune检查硬盘坏道 1.百度搜索下载HD Tune软件,注意:尽量选择系统之家官网上下载这类软件,因为系统之家上的软件不会捆绑的流氓软件 2.软件打开之后,界面如图,最上方显示硬盘的厂家信息,图示红色遮挡区 3.点击选项卡切换至错误扫描,如图,然后在红框位置,尽量

网易有道笔试总结

第一题是给你一堆坐标,找出里面可以组成矩形的点并且计算面积?忘记了,当时题目扫了一眼就直接跳过了... 第二题是一个队列中元素进行一些列的操作,输出是1,2,3,4....n按顺输出,问你原来的序列是多少. 这个其实就是每次都跳过一个可用位置然后在下一个位置放入数字,如果到达容器尾部,那么再从头开始搜索,知道全部位置都放了数字. 简直天杀的,这个最后我调出来超时了2分钟,结果自动交卷了 T   T码代码的速度很重要啊,还有OJ平台是真的烂,笔试的平台感觉一个比一个烂! 代码如下: #includ