[数学][中国剩余定理]Leapfrog

Posted lllxq

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[数学][中国剩余定理]Leapfrog相关的知识,希望对你有一定的参考价值。

题目描述

Somewhere in an animal kingdom far from here there is a large forest. Inside the forest live a large number of frogs.
Every year the frogs gather along the big central road in the forest to show the other animals their unique ability
during the Big Animal Prowess Conference (BAPC).
These frogs are experts in forming towers by climbing on top of each other. They are, however, not experts in gathering orderly on the road, so the frogs have arrived on different positions along the central road. The frogs are also notorious show offs: their every jump is as far as they can and always a prime distance. Not every frog is as strong as the others, so jumping distances may vary. Naturally, the frogs only jump to increase their position, never the other way!
The frog king wants to invite all visitors of the BAPC to marvel at the most spectacular frog tower. Multiple frog towers can be created, but the king wants to show the largest tower at the smallest possible position. He doesn’t want anyone to miss the action because they were at the wrong spot! Can you help the frog king determine the position and size of the tower?

 

输入

• On the ?rst line one integer n, the number of frogs gathering on the central road, with 1 ≤ n ≤ 40.
• Then follow n lines with integers xi and di, the initial position and prime jumping distance of the ith frog. Here 0 ≤ xi ≤ 260 and 2 ≤ di ≤ 108
. It is given that the product of all unique jumping distances is less than 109.

 

输出

Output a single line with two integers indicating:
• the smallest position of the highest frog tower,
• the size of the highest frog tower.
Separate these integers by a space.

 

样例输入

3
0 2
1 2
3 3

 

样例输出

3 2
思路:很快想到CRT,但有几个地方要小心:1.余数a=aa(起始位置)%p(模数);2.p相同但a不同的青蛙不可能跳到同一点,p相同且a相同的青蛙可能有多只;3.CRT算出同余方程组的解后,要判定解是否合法,即解是否大于所选青蛙的起始位置(aa)
AC代码://写的非常极其乱
#include <iostream>
#include<cstdio>
#include<vector>
#include<map>
#include<algorithm>
typedef long long ll;
using namespace std;

struct Node{ll si,ssi,num;};bool cmp(Node a,Node b){return a.si<b.si;};
ll ss[45],dis[45],s[45];
map<ll,ll> mp;
map<ll,ll> mp_;
ll cnt=0;
vector<Node> remain[45];
ll ans=9223372036854775807,sum=0,sum_=0;
ll p[45],a[45],aa[45];

void exgcd(ll a,ll b,ll& d,ll& x,ll& y){
    if(!b){ d=a; x=1; y=0;}
    else{ exgcd(b,a%b,d,y,x); y-=x*(a/b); }
}
ll CRT(){
    ll P=p[1],A=a[1],t;
    for(ll i=2;i<=cnt;i++){
        ll d,x,y;
        exgcd(P,p[i],d,x,y);
        if((a[i]-A)%d) return -1;
        x*=(a[i]-A)/d,t=p[i]/d,x=(x%t+t)%t;
        A=P*x+A,P=P/d*p[i],A%=P;
    }
    A=(A%P+P)%P;
    for(ll i=1;i<=cnt;i++){//重点3
        if(A<aa[i]) A+=(aa[i]-A)/P*P;
        while(A<aa[i]) A+=P;
    }
    return A;
}

void dfs(ll x){
  if(x==0){
    ll tmp=CRT();
    //重点4
    if(sum>sum_) {sum_=sum,ans=tmp;}
    if(sum==sum_&&tmp<ans) ans=tmp;
    return;
  }
  for(ll i=0;i<(ll)remain[x].size();i++){
    a[x]=remain[x][i].si;p[x]=mp_[x];
    aa[x]=remain[x][i].ssi;
    sum+=remain[x][i].num;
    dfs(x-1);
    sum-=remain[x][i].num;
  }
}

int main()
{
    ll n;scanf("%lld",&n);
    for(ll i=1;i<=n;i++){
        scanf("%lld%lld",&ss[i],&dis[i]),s[i]=ss[i]%dis[i];//重点1
        if(!mp[dis[i]]){
            mp[dis[i]]=++cnt;
            mp_[cnt]=dis[i];
        }
        remain[mp[dis[i]]].push_back(Node{s[i],ss[i],1});
    }
    for(ll i=1;i<=cnt;i++){//重点2
        sort(remain[i].begin(),remain[i].end(),cmp);
        for(ll j=1;j<(ll)remain[i].size();j++){
            if(remain[i][j].si==remain[i][j-1].si) remain[i][j].num+=remain[i][j-1].num;
        }
    }
    dfs(cnt);
    printf("%lld %lld
",ans,sum_);
    return 0;
}

以上是关于[数学][中国剩余定理]Leapfrog的主要内容,如果未能解决你的问题,请参考以下文章

中国数学剩余定理

什么叫中国剩余定理

信息安全数学基础中国剩余定理

bzoj 1951: [Sdoi2010]古代猪文 中国剩余定理+欧拉定理+组合数学+卢卡斯定理

bzoj 2142: 礼物中国剩余定理+组合数学

中国剩余定理