• BZOJ5418 NOI2018屠龙勇士(excrt)


      显然multiset求出每次用哪把剑。注意到除了p=1的情况,其他数据都保证了ai<pi,于是先特判一下p=1。比较坑的是还可能存在ai=pi,稍微考虑一下。

      剩下的部分即解bix≡ai(mod pi)方程组。没有保证模数互质,于是excrt一发。excrt实际上就是不停exgcd合并两个方程。

      这次是重开这题,调了半天还是一堆-1觉得这个题可能是搞不会了,最后才发现某个地方没开long long。

    #include<iostream> 
    #include<cstdio>
    #include<cmath>
    #include<cstdlib>
    #include<cstring>
    #include<algorithm>
    #include<set>
    #include<cassert>
    using namespace std;
    #define ll long long
    #define N 100010
    char getc(){char c=getchar();while ((c<'A'||c>'Z')&&(c<'a'||c>'z')&&(c<'0'||c>'9')) c=getchar();return c;}
    ll gcd(ll n,ll m){return m==0?n:gcd(m,n%m);}
    ll lcm(ll n,ll m){return n*(m/gcd(n,m));}
    ll read()
    {
        ll x=0,f=1;char c=getchar();
        while (c<'0'||c>'9') {if (c=='-') f=-1;c=getchar();}
        while (c>='0'&&c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar();
        return x*f;
    }
    int T,n,m;
    ll b[N],p[N],a[N],rwd[N];
    multiset<ll> q; 
    ll ksc(ll a,ll b,ll p)
    {
        ll t=a*b-(ll)((long double)a*b/p+0.5)*p;
        return t<0?t+p:t;
    }
    void exgcd(ll a,ll b,ll &x,ll &y)
    {
        if (b==0)
        {
            x=1,y=0;
            return;
        }
        exgcd(b,a%b,x,y);
        ll t=x;x=y;y=t-a/b*x;
    }
    int main()
    {
    #ifndef ONLINE_JUDGE
        freopen("bzoj5418.in","r",stdin);
        freopen("bzoj5418.out","w",stdout);
        const char LL[]="%I64d
    ";
    #else
        const char LL[]="%lld
    ";
    #endif
        T=read();
        while (T--)
        {
            n=read(),m=read();
            for (int i=1;i<=n;i++) a[i]=read();
            for (int i=1;i<=n;i++) p[i]=read();
            for (int i=1;i<=n;i++) rwd[i]=read();
            q.clear();
            for (int i=1;i<=m;i++) q.insert(read());
            for (int i=1;i<=n;i++)
            {
                multiset<ll>::iterator it=q.upper_bound(a[i]);
                if (it!=q.begin()) it--;
                b[i]=*it;q.erase(it);q.insert(rwd[i]);
            }
            bool issp=1;
            for (int i=1;i<=n;i++) if (p[i]!=1) {issp=0;break;}
            ll ans=0;
            if (issp) for (int i=1;i<=n;i++) ans=max(ans,(a[i]-1)/b[i]+1);
            else
            {
                 issp=1;
                for (int i=1;i<=n;i++) if (a[i]!=p[i]) {issp=0;break;}
                if (issp)
                {
                    ans=1;
                    for (int i=1;i<=n;i++)
                    if (b[i]%p[i]) b[i]%=p[i],ans=lcm(ans,p[i]/gcd(b[i],p[i]));
                }
                else
                {
                    for (int i=1;i<=n;i++)
                    if (b[i]%p[i]==0&&a[i]!=b[i]||a[i]%gcd(b[i],p[i])) {ans=-1;break;}
                    else
                    {
                        b[i]%=p[i];
                        int x=gcd(b[i],p[i]);
                        a[i]/=x,b[i]/=x,p[i]/=x;
                    }
                    if (~ans)
                    {
                        ll tmp;exgcd(b[1],p[1],ans,tmp);ans=(ans%p[1]+p[1])%p[1];ans=ksc(ans,a[1],p[1]);
                        for (int i=2;i<=n;i++)
                        {
                            ll A=ksc(b[i],p[i-1],p[i]),B=(a[i]-ksc(b[i],ans,p[i])+p[i])%p[i];
                            ll x=gcd(p[i],p[i-1]);if (B%x) {ans=-1;break;}
                            A/=x,B/=x,p[i]/=x;
                            ll k;exgcd(A,p[i],k,tmp);k=(k%p[i]+p[i])%p[i];k=ksc(k,B,p[i]);
                            p[i]*=p[i-1];ans=(ksc(k,p[i-1],p[i])+ans)%p[i];
                        }
                    }
                }
            }
            printf(LL,ans);
        }
        return 0;
    }
  • 相关阅读:
    按钮水波纹效果
    点击水波纹效果
    实现图片上传预览效果
    css 实现鼠标滑过流光效果
    插件地址参考
    移动前端经验
    移动端开发需要加的meta
    25款css动画库
    oracle 中的next_day函数
    Oracle replace函数
  • 原文地址:https://www.cnblogs.com/Gloid/p/10181105.html
Copyright © 2020-2023  润新知