zoukankan      html  css  js  c++  java
  • Luogu P4774 [NOI2018]屠龙勇士

    题面

    题面和数据范围建议看原题。

    题解

    注意到每一次打龙的时候选择的剑都是唯一固定的,而且注意到同一攻击力的剑可以有多把,所以可以用 multiset 来维护一下。

    所以现在打每一条龙相当于一个方程 (atk_ix+p_iy=a_i),移项得到 (atk_ixequiv a_ipmod{a_i}),直接使用 exCRT 即可。

    这里我的代码是边打龙边合并方程,其实也可以确定下来剑之后逐一合并方程,long longlong long 可以直接龟速乘。

    判断无解的情况比较麻烦,建议对代码看。

    代码

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long int ll;
    const ll MAXN=1e5+51;
    ll test,n,m,xx,yy,kk,mx,c,g;
    ll x[MAXN],y[MAXN],p[MAXN];
    multiset<ll>st;
    multiset<ll>::iterator it;
    inline ll read()
    {
        register ll num=0,neg=1;
        register char ch=getchar();
        while(!isdigit(ch)&&ch!='-')
        {
            ch=getchar();
        }
        if(ch=='-')
        {
            neg=-1;
            ch=getchar();
        }
        while(isdigit(ch))
        {
            num=(num<<3)+(num<<1)+(ch-'0');
            ch=getchar();
        }
        return num*neg;
    } 
    inline void exgcd(ll x,ll y,ll &xx,ll &yy)
    {
        ll t;
        if(!y)
        {
            return (void)(xx=1,yy=0,g=x);
        }
        exgcd(y,x%y,xx,yy),t=xx,xx=yy,yy=t-x/y*yy;
    }
    inline ll mul(ll x,ll y,ll md)
    {
        ll res=0;
        while(y)
        {
            if(y&1)
            {
                res=(res+x)%md;
            }
            x=(x<<1)%md,y>>=1;
        }
        return res;
    }
    inline void solve()
    {
        n=read(),m=read();
        for(register int i=1;i<=n;i++)
        {
            x[i]=read();    
        }
        for(register int i=1;i<=n;i++)
        {
            p[i]=read();
        }
        for(register int i=1;i<=n;i++)
        {
            y[i]=read();
        }
        st.clear();
        for(register int i=1;i<=m;i++)
        {
            st.insert(read());
        }
        mx=c=0,m=1;
        for(register int i=1;i<=n;i++)
        {
            it=st.upper_bound(x[i]),it!=st.begin()?--it:it,kk=*it,st.erase(it);
            st.insert(y[i]),mx=max(mx,(x[i]-1)/kk+1),kk%=p[i],x[i]%=p[i];
            if(!kk&&x[i])
            {
                return (void)puts("-1");
            }
            if(!kk&&!x[i])
            {
                continue;
            }
            exgcd(kk,p[i],xx,yy);
            if(x[i]%g)
            {
                return (void)puts("-1");
            }
            p[i]/=g,x[i]=mul(x[i]/g,(xx%p[i]+p[i])%p[i],p[i]),exgcd(m,p[i],xx,yy);
            if((x[i]-c)%g)
            {
                return (void)puts("-1");
            }
            m=m/g*p[i],c=(c+mul(mul(m/p[i],((x[i]-c)%m+m)%m,m),(xx%m+m)%m,m))%m;
        }
        printf("%lld
    ",c>=mx?c:c+m*((mx-c-1)/m+1));
    }
    int main()
    {
        test=read();
        for(register int i=0;i<test;i++)
        {
            solve();
        }
    }
    
  • 相关阅读:
    13.numpy线性代数和绘图
    12-numpy矩阵
    11-numpy视图与副本
    10-numpy排序搜索
    day12 异常 模块 单例
    day11面向对象 多态 静态方法 (三)
    day 10 面向对象(=)
    day9 面向对象
    day8 文件
    day7 地址 名片管理系统
  • 原文地址:https://www.cnblogs.com/Karry5307/p/13489563.html
Copyright © 2011-2022 走看看