zoukankan      html  css  js  c++  java
  • BZOJ_5418_[Noi2018]屠龙勇士_exgcd+excrt

    BZOJ_5418_[Noi2018]屠龙勇士_exgcd+excrt

    Description

    www.lydsy.com/JudgeOnline/upload/noi2018day2.pdf


    每次用哪吧剑显然用个set就搞定了。

    对于每头龙,生命值ai,回血pi,剑的攻击力为atk,打的次数为ans。

    显然有ans*atk-ai>=0&&pi|ans*atk-ai。

    ans*atk+pi*y=ai (y<=0)。

    要求y<=0的前提下ans尽量的小,是一个ax+by=n的形式,exgcd直接做。

    然后得到n个方程,每个方程形如ans mod ai=bi。

    ai不一定互质,直接上excrt。

    感觉excrt一定程度上比crt还好理解。

    大概就是个不断用exgcd合并的过程吧,自己想应该也能想出来。

    代码:

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <cstdlib>
    #include <cmath>
    #include <set>
    using namespace std;
    typedef long long ll;
    #define N 100050
    int n,m,da[N];
    ll a[N],p[N],mods[N],q[N];
    ll Abs(ll x) {return x>0?x:-x;}
    multiset<ll>S;
    ll ch(ll x,ll y,ll mod) {
        ll re=0; for(;y;y>>=1ll,x=(x+x)%mod) if(y&1ll) re=(re+x)%mod; return re; 
    }
    void exgcd(ll a,ll b,ll &x,ll &y,ll &p) {
        if(!b) {p=a; x=1; y=0; return ;}
        exgcd(b,a%b,y,x,p),y-=a/b*x;
    }
    ll gcd(ll x,ll y) {return y?gcd(y,x%y):x;}
    void init() {
        S.clear();
    }
    int find(ll x) {
        multiset<ll>::iterator it;
        it=S.upper_bound(x);
        if(it!=S.begin()) {
            it--;
        }
        int tmp=*it;
        S.erase(it); 
        return tmp;
    }
    ll exCRT() {
        int i;
        ll M=mods[1],A=q[1],t,d,x,y;
        for(i=1;i<=n;i++) {
            exgcd(M,mods[i],x,y,d);
            if((q[i]-A)%d) return -1;
            t=mods[i]/d;
            x=(x%t+t)%t;
            x=ch(x,(((q[i]-A)/d)%t+t)%t,t);
            A=M*x+A; M=M/d*mods[i]; A=A%M;
        }
        A=(A%M+M)%M;
        return A;
    }
    void solve() {
        init();
        scanf("%d%d",&n,&m);
        int i,x;
        for(i=1;i<=n;i++) scanf("%lld",&a[i]);
        for(i=1;i<=n;i++) scanf("%lld",&p[i]);
        for(i=1;i<=n;i++) scanf("%d",&da[i]);
        for(i=1;i<=m;i++) {
            scanf("%d",&x); S.insert(x);
        }
        ll mx=0;
        int flg=0;
        for(i=1;i<=n;i++) {
            ll D=find(a[i]),P=p[i],A=a[i],X,Y,d,td=D,tp=P,ta=A;
            if(p[i]==1) {mx=max(mx,(a[i]+D-1)/D); flg=1; S.insert(da[i]); continue;}
            exgcd(D,P,X,Y,d);mods[i]=P/d;
            if(A%d) {puts("-1"); return ;}
            D/=d; P/=d; A/=d;
            D=Abs(D);
            Y=(ch(Y,A,D)+D)%D;
            if(Y>0) Y-=D;
            X=(ta-tp*Y)/td;
            q[i]=X;
            S.insert(da[i]);
        }
        if(flg) printf("%lld
    ",mx);
        else printf("%lld
    ",exCRT());
    }
    int main() {
        // freopen("dragon.in","r",stdin);
        // freopen("dragon.out","w",stdout);
        int T;
        scanf("%d",&T);
        while(T--) solve();
    }
    
  • 相关阅读:
    r.json和json.loads 区别,以及json和字符串转换
    HTTPIE 工具使用入门
    PyCharm 专业版 2018 永久有效
    linux 执行:pip3 install -r requirements.txt 报错
    fiddler过滤指定的请求
    fiddler抓取https的请求详解
    centos6.5 内核 :2.6.32 升级内核
    -bash: /usr/bin/yum: /usr/bin/python: bad interpreter: No such file or directory
    ODI中web service介绍
    Oracle GoldenGate 12c中的协同交付(Coordinated Delivery)
  • 原文地址:https://www.cnblogs.com/suika/p/9426862.html
Copyright © 2011-2022 走看看