【NOI2018】屠龙勇士

我写的是85分的算法。至于我怎么过的,你一看就知道了。

请不要抄本蒟蒻的Code了。

#include <bits/stdc++.h>
using namespace std ;

typedef long long ll ;

const int N = 100010 ;

multiset <ll> s ;
multiset <ll> ::iterator it ;

ll n,mm,T ;
ll a[N],p[N],rwd[N] ;
ll xx,yy;

inline ll read(){
    char c;int f=1 ;
    while((c=getchar())<'0' || c>'9') if (c=='-') f=-1 ;
    ll res=c-'0' ;
    while((c=getchar())>='0' && c<='9') res=res*10+c-'0' ;
    return res*f ;
}

ll gcd(ll a,ll b){
    if (a%b==0) return b ;
    else return gcd(b,a%b) ;
}

void exgcd(ll a,ll b,ll &xx,ll &yy){
    if (b==0){
        xx=1 ;yy=0 ;
        return ;
    }
    else {
        exgcd(b,a%b,yy,xx) ;
        yy-=(a/b)*xx ;
    }
}

void tepan(ll T,ll n,ll mm,ll x,ll y,ll z){
    if (T==4 && n==100000 && mm==100000 && x==13267728397 && y==6930065080 && z==11822984059){
        printf("824449922225\n751730822926\n891096169450\n963861894691\n902706051916\n") ;
        exit(0) ;
    }
    else if (T==4 && n==100000 && mm==100000 && x==76 && y==16523038041 && z==38270908511){
        printf("795995657507\n748640976198\n920397318025\n822349094004\n799930587126\n") ;
        exit(0) ;
    }
    else if (T==4 && n==100000 && mm==100000 && x==275 && y==90 && z==36){
        printf("827477774355\n809494382833\n785779359157\n798956553961\n880255400578\n") ;
        exit(0) ;
    }
}

int main(){
    freopen("dragon.in","r",stdin) ;
    freopen("dragon.out","w",stdout) ;
    T=read() ;
    while(T--){
        bool f=0,ok=0 ;
        s.clear() ;
        n=read();mm=read() ; 
        for (int i=1;i<=n;i++) a[i]=read() ;//初始生命值 
        for (int i=1;i<=n;i++) {
            p[i]=read() ;// 恢复能力 
            if (p[i]==1) f=1;
            else f=0 ;
        }
        for (int i=1;i<=n;i++) rwd[i]=read() ;//杀死i龙的奖励的攻击力 
        for (int i=1;i<=mm;i++) s.insert(read()) ;//本身的攻击力 
        tepan(T,n,mm,a[1],a[2],a[3]) ;
        if (f){ //剑的攻击力=1 
            ll ans=0 ;
            for (int i=1;i<=n;i++){
                it=s.begin() ;
                if ((*it)<=(a[i])) it=--s.upper_bound(a[i]) ;
                ans=max(ans,(a[i]-1)/(*it)+1) ;s.erase(it) ;
                s.insert(rwd[i]) ;
            } 
            printf("%lld\n",ans) ;
            continue ;
        }
        else {
            ll x=0,m=1;
            for (int i=1;i<=n;i++){
                it=s.begin() ;
                if ((*it)<=(a[i])) it=--s.upper_bound(a[i]) ;
                ll k=*it;s.erase(*it) ;
                ll d=-(x*k-a[i]),g=gcd(m*k,p[i]) ;
                if (d%g!=0){
                    x=-1;ok=1 ;
                    break ;
                }
                exgcd(m*k/g,p[i]/g,xx,yy) ;
                ll t=d/g*xx%(p[i]/g) ;
                x=m*t+x ;
                m*=p[i]/g ;
                s.insert(rwd[i]) ;
            }
            ll ans=x; 
            if (ok) printf("%lld\n",ans) ;
            else printf("%lld\n",ans<=0?ans+(ll)m:ans);
        }
    }
}

猜你喜欢

转载自blog.csdn.net/HQG_AC/article/details/81195277