PERIODNB - PERIOD

Tác giả: ladpro98

Ngôn ngữ: Pascal

program periodnb;
uses    math;
const   fi='';
        maxN=10000007;
type    e=record
        val:int64;
        pos,carry:longint;
        end;
var     a,timer:array[-1..maxN] of int64;
        stack:array[-1..maxN] of e;
        n,head,tail:longint;
        p,q,m,time,res:int64;

procedure input;
var     f:text;
        i:longint;
begin
        assign(f,fi);
        reset(f);
        readln(f,n,time);
        readln(f,p,q,m);
        close(f);
end;

procedure init;
var     i:longint;
        t,pp:int64;
begin
        pp:=0;
        p:=p mod m;
        for i:=1 to n do
        begin
                pp:=pp+p;
                while pp>=m do pp:=pp-m;
                a[i]:=pp + q;
        end;
        for i:=n+1 to n shl 1 do
        a[i]:=a[i-n];
        timer[0]:=0;
        for i:=1 to n shl 1 do
        timer[i]:=timer[i-1]+time;
        for i:=1 to n do
               a[i]:=a[i]+timer[i];
        head:=1;tail:=0;
        res:=high(int64);
end;

procedure process;
var     i:longint;
begin
        for i:=1 to n do
        begin
                while (head<=tail) and (stack[tail].val<=a[i]) do dec(tail);
                inc(tail);
                stack[tail].val:=a[i];
                stack[tail].pos:=i;
                stack[tail].carry:=0;
        end;
        for i:=n+1 to n shl 1 do
        begin
                inc(stack[tail].carry);
                if head<>tail then
                inc(stack[head].carry);
                while (head<=tail) and (stack[head].pos<=(i-n)) do
                begin
                        inc(Head);
                        if head<>tail then
                        inc(stack[head].carry,stack[head-1].carry);
                end;
                a[i]:=a[i]+timer[n];
                while (head<=tail) and ((stack[tail].val-timer[stack[Tail].carry])<=a[i]) do
                begin
                        dec(tail);
                        if head<tail then
                        inc(stack[tail].carry,stack[tail+1].carry);
                end;
                inc(tail);
                stack[tail].val:=a[i];
                stack[tail].pos:=i;
                stack[tail].carry:=0;
                res:=min(res,stack[head].val-timer[stack[Head].carry]);
        end;
end;

begin
        input;
        init;
        process;
        write(res);
end.



Download