首页 > 代码库 > [CQOI 2014] 数三角形 & 机械排序臂

[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