[LOJ # 3144] [APIO2019] strange device (number theory)

[LOJ # 3144] [APIO2019] strange device (number theory)

Face questions

SIZE

answer

Suddenly found \ (LOJ \) have the \ (APIO \) of the title it, do a hurry to do.
This title is cut on the nest exam questions wailing. After writing the violence again shook launched a positive solution. . .


Consider \ (t1, t2 \) two points in time, if the two time \ ((x, y) \ ) equal, is to consider what kind of situation.
\ [\ begin {cases} t_1 + [\ frac {t_1} {B}] \ equiv t_2 + [\ frac {t_2} {B}] (\ mod A) \\ t_1 \ equiv t_2 (\ mod B) \ end { cases} \]
then according to a second condition, so that we might \ (T_2 T_l = kB +, K> 0, K \ in the Z \) .
Then brought to the first formula is:
\ [T_l + [\ FRAC T_l {} {B}] \ equiv T_l + kB + K + [\ FRAC {T1} {B}] (\ MOD A) \]
Simplification after obtaining
\ [k (B + 1)
\ equiv 0 (\ mod A) \] and \ (A, B \) are constants, so \ (\ frac {A} { gcd (A, B + 1)} | k \) . Order \ (G = \ {A} {FRAC GCD (A, B +. 1)} \) , so \ (G | K \) .
So \ (k \) If \ (g \) multiple of the time will meet this condition. The \ (t_1 \ mod B \) of the total value of \ (B \) species, it is not difficult to get circulation section\ (T = gB \) .
Then all \ (l, r \) after a modulo obtained strip line, line segment \ ([0, T) \ ) covering the total length of the interval is the answer, the difference can be calculated simply answers.

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<set>
using namespace std;
#define ll long long
#define MAX 1000100
inline ll read()
{
    ll x=0;bool t=false;char ch=getchar();
    while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
    if(ch=='-')t=true,ch=getchar();
    while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();
    return t?-x:x;
}
ll n,sum,l[MAX],r[MAX],A,B,d,T,ans;
multiset<pair<ll,int> >S;
#define mp make_pair
void Add(ll l,ll r){S.insert(mp(l,1));S.insert(mp(r+1,-1));}
int main()
{
    n=read();A=read();B=read();d=__gcd(A,B+1);
    for(int i=1;i<=n;++i)l[i]=read(),r[i]=read(),sum+=r[i]-l[i]+1;
    if(1.0*A*B/d>1e18){printf("%lld\n",sum);return 0;}
    T=A/d*B;
    for(int i=1;i<=n;++i)
    {
        if(r[i]-l[i]+1>=T){printf("%lld\n",T);return 0;}
        if(l[i]/T!=r[i]/T)Add(l[i]%T,T-1),Add(0,r[i]%T);
        else Add(l[i]%T,r[i]%T);
    }
    S.insert(mp(T,0));
    ll lst=-1,c=0;
    for(auto a:S)
    {
        if(c>0)ans+=a.first-lst;
        c+=a.second;
        lst=a.first;
    }
    printf("%lld\n",ans);
    return 0;
}

Guess you like

Origin www.cnblogs.com/cjyyb/p/11093726.html