MYSTERY – SPOJ

Đề bài: http://vn.spoj.com/problems/MYSTERY/

Thuật toán:

  • (đang cập nhập)

Code:

const
    x=20122007;
type int64 = qword;

var
    n,i : longint;
    f : array[0..1000000] of longint;
    res : int64;

function getVal(a:longint):longint;
var
    p,q,i : longint;
    g : int64;
begin
    if a<=1000000 then exit(f[a])
    else
    begin
        p:=a mod 1000000;
        q:=a div 1000000;
        g:=f[p];
        for i:=1 to q do g:=(g*f[1000000]) mod x;
        exit(g);
    end;
end;

begin
    readln(n);

    f[0]:=1;
    for i:=1 to 1000000 do f[i]:=(f[i-1]*3) mod x;

    res:=1;
    if sqr(trunc(sqrt(n))) = n then
    begin
      for i:=1 to trunc(sqrt(n))-1 do
      if n mod i=0 then
      res:=(((res*(getVal(i)-1)) mod x)*(getVal(n div i)-1)) mod x;

      res:=(res*(getVal(trunc(sqrt(n)))-1)) mod x;
  end else
  begin
    for i:=1 to trunc(sqrt(n)) do
      if n mod i=0 then
        res:=(((res*(getVal(i)-1)) mod x)*(getVal(n div i)-1)) mod x;
  end;

    writeln(res);
end.

KDEL – SPOJ

Đề bài: http://vn.spoj.com/problems/KDEL/

Thuật toán: 

  • (đang cập nhập)

Code:

const fi='';
      fo='';
      maxn=700000;
var   i,j:longint;
      f:text;
      n,k,d:longint;
      tam:array[1..maxn] of boolean;
      ngto:array[1..50000] of longint;
      hold,res:ansistring;
procedure nhap;
begin
    assign(f,fi);reset(f);
    readln(f,n,k);
    close(f);
end;
procedure sang;
begin
    tam[1]:=true;
    for i:=2 to trunc(sqrt(maxn)) do
      if tam[i]=false then
        begin
             j:=i*i;
             while j<=maxn do
                   begin
                       tam[j]:=true;
                       j:=j+i;
                   end;
        end;
    d:=0;
    for i:=2 to maxn do
      if tam[i]=false then
         begin
             inc(d);
             ngto[d]:=i;
             if d=n then exit;
         end;
end;
procedure xuly;
var       tmp,tam:ansistring;
          le,leres:int64;
begin
    sang;




    for i:=1 to n do
      begin
          str(ngto[i],tmp);
          hold:=hold+tmp;
      end;

    le:=length(hold);
    leres:=le-k;

    for i:=1 to le do
      begin
          while (k>0) and (length(res)>0) and (res[length(res)]leres do
        begin
            delete(res,length(res),1);
        end;


end;
procedure xuat;
begin
    assign(f,fo);rewrite(f);
    writeln(f,res);
    close(f);
end;
begin
    nhap;
    xuly;
    xuat;
end.

DHSERV – SPOJ

Đề bài: http://vn.spoj.com/problems/DHSERV/

Thuật toán:

  • Bài này thuần sử dụng thuật toán Floyd. Các bạn có thể tham khảo code bên dưới để hiểu thêm.

Code:

const
  fi='';//hserv.inp';
  fo='';//dhserv.out';
  maxn=500;
  oo=trunc(1e18);
var
  a : array[1..maxn,1..maxn] of int64;
  d : array[1..maxn,1..maxn] of int64;
  i,j,n,m,k : longint;
procedure enter;
  var u,v,w : longint;
  begin
    assign(input,fi);reset(input);
    readln(n,m,k);
    for i:=1 to n do
      for j:=1 to n do
        if i<>j then
          begin
            d[i,j] := oo;
            a[i,j] := oo;
          end else
          begin
            d[i,j] := 0;
            a[i,j] := 0;
          end;
    for i:=1 to m do
      begin
        read(u,v,w);
        a[u,v] := w;
        d[u,v] := w;
      end;
  end;
procedure process;
  var tg,kieu,u,v,kk : longint;
  begin
    assign(output,fo);rewrite(output);
    for kk:=1 to k do
      begin
        read(kieu);
        if kieu=1 then
          begin
            read(tg);
            for u:=1 to n do
              for v:=1 to n do
                if d[u,v] > d[u,tg] + d[tg,v] then
                  begin
                    d[u,v] := d[u,tg] + d[tg,v];
                  end;
          end;
        if kieu=2 then
          begin
            read(u,v);
            if d[u,v]=oo then writeln(-1) else
            writeln(d[u,v]);
          end;
      end;
      close(output);
  end;
begin
  enter;
  process;
end.

SPSEQ – SPOJ

Đề bài: http://vn.spoj.com/problems/SPSEQ/

Thuật toán:

  • Gọi f1[i] là độ dài dãy con không giảm dài nhất kết thúc là a[i] của dãy a[1..i]
  • Gọi f2[i] là độ dài dãy con không tăng dài nhất bắt đầu là a[i] của dãy a[i..n]
  • Kết quả bài toán là:
    2*min(f1[i],f2[i]) -1   với i=1..n;

Code:

uses    math;
const   fi='';
        fo='';
        maxn=trunc(1e5)+3;
        oo=trunc(1e9)+7;
var     a:array[0..maxn] of longint;
        b1,b2:array[0..maxn] of longint;
        f1,f2:array[0..maxn] of longint;
        i,j,n,m,res:longint;
procedure enter;
begin
        assign(input,fi);reset(input);
        readln(n);
        for i:=1 to n do read(a[i]);
        close(input);
end;
function tim1(r,x:longint):longint;
var     d,c,g:longint;
begin
        d:=0;c:=r;
        g:=(d+C) div 2;
        while (g<>d) and (g<>c) do
                begin
                        if b1[g]>=x then c:=g else d:=g;
                        g:=(d+c) div 2;
                end;
        for g:=c downto d do
                begin
                        if b1[g]d) and (g<>c) do
                begin
                        if b2[g]>=x then c:=g else d:=g;
                        g:=(d+c) div 2;
                end;
        for g:=c downto d do
                if b2[g]res1 then
                                begin
                                        inc(res1);
                                        b1[res1]:=a[i];
                                end else
                        if b1[tam1+1]>a[i] then b1[tam1+1]:=a[i];
                        f1[i]:=tam1+1;
                end;
        res2:=1;
        b2[0]:=-oo;
        f2[n]:=1;
        b2[1]:=a[n];
        for i:=n-1 downto 1 do
                begin
                        tam2:=tim2(res2,a[i]);
                        if tam2+1>res2 then
                                begin
                                        inc(res2);
                                        b2[res2]:=a[i];
                                end else
                                if b2[tam2+1]>a[i] then b2[tam2+1]:=a[i];
                        f2[i]:=tam2+1;
                end;
        res:=0;
        for i:=1 to n do
                res:=max( res, 2*min(f1[i],f2[i]) -1 );
end;
procedure print;
begin
        assign(output,fo);rewrite(Output);
        writeln(res);
        close(output);
end;
begin
        enter;
        process;
        print;
end.

NKFLOW – SPOJ

Đề bài: http://vn.spoj.com/problems/NKFLOW/

Thuật toán:

  • Bài này đơn thuần sử dụng thuật toán luồng. Bạn có thể tham khảo về thuật toán luồn tại:

Code:

{$MODE OBJFPC}
program MaximumFlow;
const
  InputFile  = '';
  OutputFile = '';
  maxN = Round(1E5);
  maxM = Round(1E5);
  maxC = Round(1E9);
type
  TEdge = record
    x, y: Integer;
    c, f: Integer;
    link, link2: Integer;
  end;
var
  fi, fo: TextFile;
  e: array[-maxM..maxM] of TEdge;
  head, head2: array[1..maxN] of Integer;
  level: array[1..maxN] of Integer;
  q: array[1..maxN] of Integer;
  front, rear: Integer;
  n, m, s, t: Integer;
  FlowValue: Int64;

procedure Enter;
var
  i: Integer;
  u, v, capacity: Integer;
begin
  ReadLn(fi, n, m, s, t);
  for i := 1 to m do
    begin
      ReadLn(fi, u, v, capacity);
      with e[i] do
        begin
          x := u; y := v; c := capacity;
        end;
      with e[-i] do
        begin
          x := v; y := u; c := 0;
        end;
    end;
end;

procedure BuildIncidentLists;
var
  i: Integer;
begin
  FillDWord(head[1], n, 0);
  FillDWord(head[2], n, 0);
  for i := -m to m do
    if i <> 0 then
      with e[i] do
        begin
          link := head[x]; head[x] := i;
          link2 := head2[y]; head2[y] := i;
        end;
end;

procedure InitZeroFlow;
var
  i: Integer;
begin
  for i := -m to m do e[i].f := 0;
  FlowValue := 0;
end;

function Min(x, y: Integer): Integer; inline;
begin
  if x < y then Result := x else Result := y;
end;

function cf(const e: TEdge): Integer; inline; //tinh du
begin
  with e do
    Result := c - f;
end;

procedure IncFlow(i: Integer; Delta: Integer); inline; //tang canh i len denta
begin
  Inc(e[i].f, Delta);
  Dec(e[-i].f, Delta);
end;

procedure BuildLevelGraph; //tinh t ve s
var
  u, v, i: Integer;
begin
  FillDWord(level[1], n, 0);
  level[t] := 1;
  q[1] := t;
  front := 1; rear := 1;
  repeat
    u := q[front]; Inc(front);
    i := head2[u];
    while i <> 0 do
      begin
        v := e[i].x; //ke
        if (cf(e[i]) > 0) and (level[v] = 0) then
          begin
            level[v] := level[u] + 1;
            if v = s then Exit;
            Inc(rear);
            q[rear] := v;
          end;
        i := e[i].link2;
      end;
  until front > rear;
end;

function Visit(u: Integer; Delta: Integer): Integer;      // tu s den t
var
  i, v: Integer;
  p, q: Integer;
begin
  if u = t then Exit(Delta);
  if level[u] = 0 then Exit(0);
  q := 0;
  i := head[u];
  while i <> 0 do
    begin
      if (cf(e[i]) > 0) and (level[e[i].y] = level[u] - 1) then
        begin
          v := e[i].y;
          p := Visit(v, Min(Delta, cf(e[i])));
          IncFlow(i, p);
          Inc(q, p);
          Dec(Delta, p);
          if Delta = 0 then Exit(q);
        end;
      i := e[i].link;
    end;
  Result := q;
end;

function AugmentFlow: Integer;
begin
  Result := Visit(s, maxC);
end;

procedure PrintResult;
var
  i: Integer;
begin
  WriteLn(fo, FlowValue);
end;

begin
  AssignFile(fi, InputFile); Reset(fi);
  AssignFile(fo, OutputFile); Rewrite(fo);
  try
    Enter;
    BuildIncidentLists;
    InitZeroFlow;
    repeat
      BuildLevelGraph;
      if level[s] = 0 then Break;
      Inc(FlowValue, AugmentFlow);
    until False;
    PrintResult;
  finally
    CloseFile(fi); CloseFile(fo);
  end;
end.

KQUERY – SPOJ

Đề bài: http://vn.spoj.com/problems/KQUERY/

Thuật toán:

  • (đang cập nhập)

Code:

const   fi      ='';
        fo      ='';
        maxN    =300000;
        maxQ    =2*trunc(1e5);

type    arr1    =array[1..maxN] of longint;
var     n, q    :longint;
        a, csa  :arr1;
        x,y,k,csk,pos,kq   :arr1;
        T       :arr1;

Procedure hv(var a,b:longint);
var     tg      :longint;
begin
        tg:=a;a:=b;b:=tg;
end;

Procedure QS1(l,r:longint);
var     i, j, tg, xx    :longint;
begin
        i:=l;
        j:=r;
        xx:=a[(i+j) div 2];
        repeat
                while a[i]xx do dec(j);
                if i<=j then
                        begin
                                hv(a[i],a[j]);
                                hv(csa[i],csa[j]);
                                inc(i);
                                dec(j);
                        end;
        until i>j;
        if lxx do dec(j);
                if i<=j then
                        begin
                                hv(k[i],k[j]);
                                hv(csk[i],csk[j]);
                                hv(x[i],x[j]);
                                hv(y[i],y[j]);
                                inc(i);
                                dec(j);
                        end;
        until i>j;
        if l0 do
                begin
                        Get:=Get+t[x];
                        x:=x-x and (-x);
                end;
end;

Procedure xuly;
var     i, j    :longint;
begin
        assign(input,fi);assign(output,fo);
        reset(input);rewrite(output);
        readln(n);
        for i:=1 to n do
                begin
                        read(a[i]);
                        csa[i]:=i;
                end;
        readln(q);
        for i:=1 to q do
                begin
                        readln(x[i],y[i],k[i]);
                        csk[i]:=i;
                end;
        QS1(1,n);
        QS2(1,q);
        for i:=1 to n do Update(i,1);
        j:=1;
        a[n+1]:=high(longint);
        for i:=1 to q do
                begin
                        while a[j]<=k[i] do
                                begin
                                        update(csa[j],-1);
                                        inc(j);
                                end;
                        if j<=n then
                                kq[csk[i]]:=Get(y[i])-Get(x[i]-1)
                        else kq[csk[i]]:=0;
                end;
        for i:=1 to q do writeln(kq[i]);
        close(input);close(output);
end;

begin
        xuly;
end.

PBCDEM – SPOJ

Đề bài: http://vn.spoj.com/problems/PBCDEM/

Thuật toán:

  • (đang cập nhập)

Code:

using namespace std;
#include
#define FOR(i, a, b) for (int i = a; i < b; i++)
#define FORE(i, a, b) for (int i = a; i <= b; i++)
#define FORD(i, a, b) for (int i = a; i >= b; i--)
const int MAXN = 5001;
const int INF = 1e9 + 7;

string f[5001][101];
int n;

string operator +(string a, string b)
{
    FORE(i, a.length(), b.length() - 1) a = '0' + a;
    FORE(i, b.length(), a.length() - 1) b = '0' + b;
    string c = a;
    int nho = 0;
    FORD(i, a.length() - 1, 0){
        int tmp = (a[i] - '0') + (b[i] - '0') + nho;
        c[i] = (tmp % 10 + '0');
        nho = tmp / 10;
    }
    if (nho) c = '1' + c;
    return c;
}

int main()
{
    ios::sync_with_stdio(false); cin.tie(0);
    cin >> n;
    //cout<<"wtf"<

CRECT – SPOJ

Đề bài: http://vn.spoj.com/problems/CRECT/

Thuật toán:

  • (đang cập nhập)

Code:

const   fi      ='';
        fo      ='';
        oo      =400;

var
        c       :Array[0..oo,0..oo] of char;
        l,h,dem:array[0..oo+1] of int64;
        m, n ,k   :longint;
        f       :array['A'..'E'] of int64;
        ans     :int64;
Function Calc(x,y,z:char):int64;
var     ans   :int64;
	i, j:longint;
begin
        fillchar(h, sizeof(h),0);
        fillchar(dem,sizeof(dem),0);
        fillchar(l,sizeof(l),0);
        ans:=0;
        for i:=1 to m do
                begin
                        for j:=1 to n do
                                begin
                                        if (c[i,j]=x) or (c[i,j]=y) or (c[i,j]=z) then begin
                                        l[j]:=j;
                                        h[j]:=h[j]+1;
                                        while h[l[j]-1]>h[j] do
                                                l[j]:=l[l[j]-1];
                                        dem[j]:=h[j]*(j-l[j]+1)+dem[l[j]-1];
                                        ans:=ans+dem[j];
                                        end
                                        else begin
                                                dem[j]:=0;
                                                l[j]:=0;
                                                h[j]:=0;
                                        end;

                                end;

                end;
        exit(ans);
end;

procedure run;
var     i, j, tg    :longint;
        s       :ansistring;
        x, y, z :char;
begin
        assign(input,fi);assign(output,fo);
        reset(input);rewrite(output);
        readln(m, n);
        ans:=0;
        for i:=1 to m do
                begin
                        readln(s);
                        for j:=1 to n do
                                c[i,j]:=s[j];
                end;
        for x:='A' to 'E' do
                f[x]:=Calc(x,x,x);
        for x:='A' to 'E' do
                for y:=succ(x) to 'E' do
                        for z:=succ(y) to 'E' do
                                ans:=ans+Calc(x,y,z)-Calc(x,x,y)-Calc(y,y,z)
                                        -Calc(z,z,x)
                                        +f[x]+f[y]+f[z];
        writeln(ans);
        close(input);close(output);

end;

begin
        run;
end.

REFORM – SPOJ

Đề bài: http://vn.spoj.com/problems/REFORM/

Thuật toán:

  • (đang cập nhập)

Code:

#include 
#define FORE(i, a, b) for(int i = a; i <= b; i++)
#define FORD(i, a, b) for(int i = a; i >= b; i--)
#define FOR(i, a, b) for(int i = a; i < b; i++)
const int MAXN = 1e5 * 5;
const int INF = 1e9 + 7;

using namespace std;

int n, m;
bool a[50][50];
typedef pair ii;
vector< ii > s1, s2;
int dem;
bool Free[50];

inline void duyet(int u)
{
    //cout< 0){
        duyet(v);
    }
}

vector< int > adj[MAXN];
int Low[MAXN], Num[MAXN], Count = 0, Pa[MAXN], C[MAXN];

inline void dfs(int u)
{
    Count++;
    Num[u] = Count;
    Low[u] = n + 1;
    C[u] = 1;
    FOR(i, 0, adj[u].size()){
        int v = adj[u][i];
        if (Pa[v] == 0){
            Pa[v] = u;
            dfs(v);
            C[u] += C[v];
            Low[u] = min(Low[u], Low[v]);
        } else
            if (Pa[u] != v) Low[u] = min(Low[u], Num[v]);
    }
}

long long sd[3];
int main()
{
    ios::sync_with_stdio(0); cin.tie(0);
    #ifndef ONLINE_JUDGE
    freopen("REFORM.inp", "r", stdin);
    freopen("REFORM.out", "w", stdout);
    #endif //MIKELHPDATKE
    cin >> n >> m;

    if (n <= 20){
        FORE(i, 1, m){
            int x, y;
            cin >> x >> y;
            a[x][y] = 1;
            a[y][x] = 1;
        }
        long long ans = 0;
        FORE(x, 1, n) FORE(y, x + 1, n) if (a[x][y] == 1){
            s2.push_back(ii(x, y));
        } else s1.push_back(ii(x, y));
        FOR(i, 0, s1.size())
        FOR(j, 0, s2.size()){
            int u1 = s1[i].first, v1 = s1[i].second;
            int u2 = s2[j].first, v2 = s2[j].second;
            a[u1][v1] = 1; a[v1][u1] = 1;
            a[u2][v2] = 0; a[v2][u2] = 0;
            memset(Free, 1, sizeof(Free));
            dem = 0;
           // cout<> u >> v;
            adj[u].push_back(v);
            adj[v].push_back(u);
        }
        int dlt = 0;
        FORE(u, 1, n) if (Pa[u] == 0){
            Pa[u] = -1;
            Count = 0;
            dfs(u);
            dlt++;
            sd[dlt] = Count;
        }
        //cout< 2){
            cout << 0 << endl;
            return 0;
        }

        //FORE(u, 1, n) cout << C[u]<<" ";cout<

BESTSPOT – SPOJ

Đề bài: http://vn.spoj.com/problems/BESTSPOT/

Thuật toán:

  • (đang cập nhập)

Code:

{$MODE OBJFPC}
Const
        fi      ='';
        fo      ='';
        maxn    =10000;
        maxm    =100000;
        maxw    =1000000000;

Type
        Arr1    =array[0..maxn] of longint;
        Arr2    =array[0..2*maxm] of longint;
        tHeap   =record
          val   :Arr1;
          pos   :Arr1;
          nheap :longint;
        end;

Var
        n,m,x   :longint;
        p       :Arr1;
        d       :Arr1;
        head    :arr1;
        link,adj:arr2;
        t       :arr2;
        heap    :theap;
        kq      :longint;
        best    :longint;
        dm      :longint;
        f       :text;

Procedure ae(u,v,w:longint);
begin
        inc(dm);
        adj[dm]:=v;
        t[dm]:=w;
        link[dm]:=head[u];
        head[u]:=dm;
end;

Procedure Nhap;
var
        i,u,v,w :longint;
begin
        assign(f,fi);
        reset(f);
        readln(f,n,x,m);
        dm:=0;
        best:=maxlongint;
        for i:=1 to n do head[i]:=0;
        for i:=1 to x do readln(f,p[i]);
        for i:=1 to m do
          begin
            readln(f,u,v,w);
            ae(u,v,w);
            ae(v,u,w);
          end;
        close(f);
end;

Procedure InitHeap(s:longint);inline;
var
        i       :longint;
begin
        With Heap do
          begin
            nheap:=1;
            for i:=1 to n do
              begin
                pos[i]:=0;
                d[i]:=maxw;
              end;
            val[1]:=s;
            pos[s]:=1;
            d[s]:=0;
          end;
end;

Function getmin:longint;inline;
var
        v       :longint;
        cha,con :longint;
begin
        With Heap do
          begin
            if nheap=0 then exit(0);
            GetMin:=val[1];
            v:=val[nheap];
            cha:=1;
            dec(nheap);
            repeat
              con:=2*cha;
              if (connheap) or (d[val[con]]>=d[v]) then break;
              val[cha]:=val[con];
              pos[val[con]]:=cha;
              cha:=con;
            until false;
            val[cha]:=v;
            pos[v]:=cha;
          end;
end;

Procedure Update(v:longint);inline;
var
        cha,con :longint;
begin
        With Heap do
          begin
            con:=pos[v];
            if con=0 then
              begin
                inc(nheap);
                con:=nheap;
              end;
            repeat
              cha:=con div 2;
              if (cha=0) or (d[val[cha]]<=d[v]) then break;
              val[con]:=val[cha];
              pos[val[cha]]:=con;
              con:=cha;
            until false;
            val[con]:=v;
            pos[v]:=con;
          end;
end;

Procedure Dijkstra(s:longint);
var
        i,u,v   :longint;
        ss      :longint;
begin
        InitHeap(s);
        repeat
          u:=getmin;
          if u=0 then break;
          i:=head[u];
          while i<>0 do
            begin
              v:=adj[i];
              if d[v]>d[u]+t[i] then
                begin
                  d[v]:=d[u]+t[i];
                  update(v);
                end;
              i:=link[i];
            end;
        until false;
        ss:=0;
        for i:=1 to x do
          if d[p[i]]=maxw then exit
            else ss:=ss+d[p[i]];
        if (sss)) then
          begin
            best:=ss;
            kq:=s;
          end;
end;

Procedure Sol;
var
        i       :longint;
begin
        For i:=1 to n do Dijkstra(i);
end;

Procedure Xuat;
begin
        assign(f,fo);
        rewrite(f);
        write(f,kq);
        close(f);
end;

begin
        Nhap;
        sol;
        xuat;
end.