[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

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

时间: 2024-10-12 16:13:31

[CQOI 2014] 数三角形 & 机械排序臂的相关文章

BZOJ 3505 CQOI 2014 数三角形 数学

题目大意:给一张m*n的网格,问这里面以网格为顶点的三角形有多少个. 思路:数学题.首先算出所有互不相同的三点对,然后减掉其中三个点在一个直线上的点对就行了.注意答案开long long. CODE: #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> using namespace std; int m,n; int Gcd(int x,int y);

bzoj 1914: [Usaco2010 OPen]Triangle Counting 数三角形——极角排序

Description 在一只大灰狼偷偷潜入Farmer Don的牛群被群牛发现后,贝西现在不得不履行着她站岗的职责.从她的守卫塔向下瞭望简直就是一件烦透了的事情.她决定做一些开发智力的小练习,防止她睡着了.想象牧场是一个X,Y平面的网格.她将N只奶牛标记为1-N (1 <= N <= 100,000),每只奶牛的坐标为X_i,Y_i (-100,000 <= X_i <= 100,000;-100,000 <= Y_i <= 100,000; 1 <= i &l

[Usaco2010 OPen]Triangle Counting 数三角形

[Usaco2010 OPen]Triangle Counting 数三角形 Time Limit: 10 Sec  Memory Limit: 64 MBSubmit: 394  Solved: 198[Submit][Status][Discuss] Description 在一只大灰狼偷偷潜入Farmer Don的牛群被群牛发现后,贝西现在不得不履行着她站岗的职责.从她的守卫塔向下瞭望简直就是一件烦透了的事情.她决定做一些开发智力的小练习,防止她睡着了.想象牧场是一个X,Y平面的网格.她将

数三角形 bzoj 1201

数三角形(1s 128MB)triangle [题目描述] 小苏看到一个这样的等边三角形:该等边三角形每边的长度为n且被分成n等份,于是每条边就有n-1个等分点.而整个三角形被连接两个不同边的等分点且平行于三角形的第三边的线段分成了n2个单位等边三角形(边长为1).下图左是n=5的情形: 小苏想知道,删除其中的一些短边后,剩下的边一共组成多少个三角形(包括所有边长为m的三角形),正立的和倒立的都算,只要三角形的3m条短边都没有被删除就算是组成一个三角形).例如,上图右就存在19个三角形. [输入

BZOJ 3505: [Cqoi2014]数三角形( 组合数 )

先n++, m++ 显然答案就是C(3, n*m) - m*C(3, n) - n*C(3, m) - cnt. 表示在全部点中选出3个的方案减去不合法的, 同一行/列的不合法方案很好求, 对角线的不合法方案cnt比较麻烦. 枚举对角线(左下-右上), 即(0, 0)-(x, y), 我们发现这种情况有(n-y)*(m-x)*2(算上左上-右下的)种, 然后中间有gcd(x, y)-1个点(不合法), 乘起来就好了. ---------------------------------------

【BZOJ3505】[Cqoi2014]数三角形 组合数

[BZOJ3505][Cqoi2014]数三角形 Description 给定一个nxm的网格,请计算三点都在格点上的三角形共有多少个.下图为4x4的网格上的一个三角形. 注意三角形的三点不能共线. Input 输入一行,包含两个空格分隔的正整数m和n. Output 输出一个正整数,为所求三角形数量. Sample Input 2 2 Sample Output 76 数据范围 1<=m,n<=1000 题解:显然要用补集法,我们只需要求出三点共线的方案数即可.方法是先枚举两端的点所形成的向

3505: [Cqoi2014]数三角形

3505: [Cqoi2014]数三角形 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 1324  Solved: 807[Submit][Status][Discuss] Description 给定一个nxm的网格,请计算三点都在格点上的三角形共有多少个.下图为4x4的网格上的一个三角形. 注意三角形的三点不能共线. Input 输入一行,包含两个空格分隔的正整数m和n. Output 输出一个正整数,为所求三角形数量. Sample Inp

Codeforces 559A Gerald&amp;#39;s Hexagon 数三角形

题意:按顺序给出一个各内角均为120°的六边形的六条边长,求该六边形能分解成多少个边长为1的单位三角形. 把单位三角形面积看做1,实际上就是求六边形面积.随便找六边形的三条互相不相邻的边,分别以这三条边为基础向外扩展一个等边三角形.就可以将原六边形补成一个大等边三角形,然后用大等边三角形面积减去补上的3个小等边三角形面积就是原来六边形的面积. 而等边三角形面积非常easy.就是边长的平方(实际就是边长为n的等边三角形能分解成n^2个边长为1的单位三角形,画个图就能理解了). #include <

Codeforces 559A Gerald&#39;s Hexagon 数三角形

题意:按顺序给出一个各内角均为120°的六边形的六条边长,求该六边形能分解成多少个边长为1的单位三角形. 把单位三角形面积看做1,实际上就是求六边形面积.随便找六边形的三条互相不相邻的边,分别以这三条边为基础向外扩展一个等边三角形,即可将原六边形补成一个大等边三角形,然后用大等边三角形面积减去补上的3个小等边三角形面积就是原来六边形的面积.而等边三角形面积很简单.就是边长的平方(实际就是边长为n的等边三角形能分解成n^2个边长为1的单位三角形,画个图就能理解了). #include <cstdi