[CQOI 2014] 数三角形 & 机械排序臂

数三角形 bzoj 3505

要知道一个公式就是(a,b)和(x,y)两点所成线段上面的整点数是gcd(a-x,b-y)-1,通过枚举原点到map上任意一点所能成的三角形,再平移,得到要去掉的三点共线的点对。

我当时弱智地弄了个O(n^6)的枚举,不过好歹还是对的拿了三十分。

= =满分程序和30分程序几乎一样长。

program triangle;
var m,n,i,j:integer;
    ans,t:qword;

function gcd(a,b:integer):integer;
begin
  if a=0 then exit(b);
  if b=0 then exit(a);
  if a mod b=0 then exit(b) else exit(gcd(b,a mod b));
end;

begin{main}
  readln(m,n);
  t:=(m+1)*(n+1);
  ans:=t*(t-1)*(t-2) div 6;
  for i:=0 to m do
    for j:=0 to n do
      if not ((i=0) and (j=0)) then
        begin
          if (i=0) or (j=0) then ans:=ans-(gcd(i,j)-1)*(m-i+1)*(n-j+1)
          else ans:=ans-2*(gcd(i,j)-1)*(m-i+1)*(n-j+1);
        end;
  writeln(ans);
end.
Triangle

机械排序臂 bzoj 3506

那天早上还是写的O(n^2)骗的30分,不过这回30和100的代码长度就差远了…
7/2开始写这题,7/2当天晚上学习&码完splay,是对的,但是之后的lazy tag,没什么资料,C++的程序又看不太懂,我调了这么多天简直崩溃了好吗!最后发现是左子树注入tag的时候不应该直接赋值true而应该赋反,这一点在switch里面想到了,但是在主程序里没想到。对着sort1.in这个n=1000的输入文件我愣了好久啊,为什么输出的前80%是对的但是之后就有的对有的不对了呢。一开始我以为是树的fa啊,lc、rc啊没消除干净,导致被删的结点又重新回来,后来发现这也不是回事…

不过还好找到了错误所在,现在整个人心情爆好!!

200行的程序,况且这还不是完全的splay…弱渣的我到时候要好好背一下…

program sort3;
var n,i,root,c,x,t,temp:longint;
    f,ff,loc,l,fa,lc,rc,da,tot:array[0..100010] of longint;
    lazy:array[0..100010] of boolean;

function dd(x,xloc,y,yloc:longint):boolean;
begin
  if x<y then exit(true);
  if (x=y) and (xloc<yloc) then exit(true);
  exit(false);
end;

function gg(x,xloc,y,yloc:longint):boolean;
begin
  if x>y then exit(true);
  if (x=y) and (xloc>yloc) then exit(true);
  exit(false);
end;

procedure qsort(l,r:longint);
var mid,mid_loc,i,j,temp:longint;
begin
  i:=l;j:=r;mid:=f[(l+r) div 2];mid_loc:=loc[(l+r) div 2];
  while i<=j do
    begin
      while dd(f[i],loc[i],mid,mid_loc) do inc(i);
      while gg(f[j],loc[j],mid,mid_loc) do dec(j);
      if i<=j then
        begin
          temp:=f[i];f[i]:=f[j];f[j]:=temp;
          temp:=loc[i];loc[i]:=loc[j];loc[j]:=temp;
          inc(i);dec(j);
        end;
    end;
  if i<r then qsort(i,r);
  if l<j then qsort(l,j);
end;

procedure lrot(p:longint);
var q:longint;
begin
  q:=fa[p];fa[p]:=fa[q];
  if q=root then root:=p else
    if q=lc[fa[q]] then lc[fa[q]]:=p else rc[fa[q]]:=p;
  lc[q]:=rc[p];
  if rc[p]<>0 then fa[rc[p]]:=q;
  rc[p]:=q;
  fa[q]:=p;
  tot[q]:=tot[lc[q]]+tot[rc[q]]+1;
  tot[p]:=tot[lc[p]]+tot[rc[p]]+1;
end;

procedure rrot(p:longint);
var q:longint;
begin
  q:=fa[p];fa[p]:=fa[q];
  if q=root then root:=p else
    if lc[fa[q]]=q then lc[fa[q]]:=p else
      rc[fa[q]]:=p;
  rc[q]:=lc[p];
  if lc[p]<>0 then fa[lc[p]]:=q;
  lc[p]:=q;
  fa[q]:=p;
  tot[q]:=tot[lc[q]]+tot[rc[q]]+1;
  tot[p]:=tot[lc[p]]+tot[rc[p]]+1;
end;

procedure switch(p:longint);
var t:longint;
begin
  if lazy[p]=false then exit;
  t:=lc[p];lc[p]:=rc[p];rc[p]:=t;
  lazy[p]:=false;
  lazy[lc[p]]:=not lazy[lc[p]];
  lazy[rc[p]]:=not lazy[rc[p]];
end;

procedure clear(p:longint);
begin
  if p=root then
    begin
      if lazy[p] then switch(p);
      exit;
    end;
  clear(fa[p]);
  if lazy[p] then switch(p);
end;

procedure splay(p:longint);
var t,tt:longint;
begin
  while p<>root do
    begin
      if p=lc[fa[p]] then //p is lc
        begin
          if fa[p]=root then lrot(p) else
            if fa[p]=lc[fa[fa[p]]] then
              begin
                lrot(fa[p]);lrot(p);
              end
            else
              begin
                lrot(p);rrot(p);
              end;
        end
      else
        begin
          if fa[p]=root then rrot(p) else
            if fa[p]=rc[fa[fa[p]]] then
              begin
                rrot(fa[p]);rrot(p);
              end
            else
              begin
                rrot(p);lrot(p);
              end;
        end;
    end;
  fa[p]:=0;
end;

procedure insert(x:longint);
var t,tt:longint;
begin
  inc(c);
  fa[c]:=0;lc[c]:=0;rc[c]:=0;da[c]:=f[x];
  if root=0 then
    begin
      root:=c;
      tot[root]:=1;
    end
  else
    begin
      t:=root;
      repeat
        begin
          tt:=t;
          if loc[x]<loc[t] then
            begin
              inc(tot[t]);
              t:=lc[t];
            end
          else
            begin
              inc(tot[t]);
              t:=rc[t];
            end;
        end;
      until t=0;
      tot[x]:=1;
      if loc[x]<loc[tt] then lc[tt]:=c else rc[tt]:=c;
      fa[c]:=tt;
      splay(c);
    end;
end;

begin
  //assign(input,'sort10.in');reset(input);
  //assign(output,'sort10.out');rewrite(output);
  fillchar(lazy,sizeof(lazy),false);
  readln(n);
  for i:=1 to n do
    begin
      read(f[i]);
      loc[i]:=i;
    end;
  ff:=f;
  qsort(1,n);
  for i:=1 to n do
    begin
       f[i]:=i;
    end;
  for i:=1 to n do
    insert(i);     //buildtree
  for i:=1 to n do
    begin
      clear(i);
      splay(i);
      write(tot[lc[i]]+i,' ');
      lazy[lc[i]]:=not lazy[lc[i]]; //oh no I wrote':=true' and debuged for 3 days..
      t:=lc[i];
      if lazy[t] then switch(t);
      while rc[t]<>0 do
        begin
          t:=rc[t];
          if lazy[t] then switch(t);
        end;
      fa[rc[i]]:=0;fa[lc[i]]:=0;root:=lc[i];temp:=rc[i];tot[i]:=0;
      if lc[i]=0 then root:=rc[i];
      rc[i]:=0;lc[i]:=0;fa[i]:=0;
      if t<>0 then
        begin
          clear(t);//from down to top then top to down
          splay(t);
          fa[temp]:=t;rc[t]:=temp;tot[t]:=tot[t]+tot[rc[t]];
        end
    end;
  //close(input);close(output);
end.
Sort

 

原文地址:https://www.cnblogs.com/Sky-Grey/p/3831850.html