• LG P4774 [NOI2018]屠龙勇士


    Description

    小 D 最近在网上发现了一款小游戏。游戏的规则如下:

    - 游戏的目标是按照编号 $1 ightarrow n$ 顺序杀掉 $n$ 条巨龙,每条巨龙拥有一个初始的生命值 $a_i$ 。同时每条巨龙拥有恢复能力,当其使用恢复能力时,它的生命值就会每次增加 $p_i$ ,直至生命值非负。只有在攻击结束后且当生命值 **恰好** 为 $0$ 时它才会死去。
    - 游戏开始时玩家拥有 $m$ 把攻击力已知的剑,每次面对巨龙时,玩家只能选择一把剑,当杀死巨龙后这把剑就会消失,但作为奖励,玩家会获得全新的一把剑。

    小 D 觉得这款游戏十分无聊,但最快通关的玩家可以获得 ION2018 的参赛资格,于是小 D 决定写一个笨笨的机器人帮她通关这款游戏,她写的机器人遵循以下规则:

    - 每次面对巨龙时,机器人会选择当前拥有的,攻击力不高于巨龙初始生命值中攻击力最大的一把剑作为武器。如果没有这样的剑,则选择 **攻击力最低** 的一把剑作为武器。
    - 机器人面对每条巨龙,它都会使用上一步中选择的剑攻击巨龙固定的 $x$ 次,使巨龙的生命值减少 $x imes ATK$ 。
    - 之后,巨龙会不断使用恢复能力,每次恢复 $p_i$ 生命值。若在使用恢复能力前或某一次恢复后其生命值为 $0$ ,则巨龙死亡,玩家通过本关。

    那么显然机器人的攻击次数是决定能否最快通关这款游戏的关键。小 D 现在得知了每条巨龙的所有属性,她想考考你,你知道应该将机器人的攻击次数 $x$ 设置为多少,才能用最少的攻击次数通关游戏吗?

    当然如果无论设置成多少都无法通关游戏,输出 $-1$ 即可。

    Solution

    对于每一条龙的攻击力是已知的,可以用平衡树维护

    设当前这一条龙对应的剑攻击力为$k$,攻击次数为$x$,那么必须满足:

    $$kx equiv a pmod p 且 kx geq a$$

    那么就是解形如$kx equiv a pmod p$的线性方程组

    考虑一个其他问题:解形如$x equiv c$的线性方程组:

    $$egin{cases}xequiv c_1(mod m_1)\xequiv c_2(mod m_2)end{cases}$$

    先转化为一般方程:

    $$egin{cases}x=c_1+m_1x_1\x=c_2+m_2x_2end{cases}$$

    两式相等:

    $$m_1x_1+m_2x_2=c_2-c_1$$

    用Exgcd求$x_1$的一个解$x'$,$g=gcd(m_1,m_2)$,通解$frac{c_2-c_1}gx'+frac{m_2}gt(tin Z)$

    将通解代回一式得

    $$xequiv c_1+frac{m_1(c_2-c_1)}gx'(mod {frac{m_1m_2}gt})$$

    现在考虑解形如$kx equiv a pmod p$的方程组,设总方程为$xequiv c pmod m$

    设$g=gcd(k,p)$,用Exgcd解$x'$,得$xequivfrac a gx'(modfrac p g)$

    变成了上一个问题

    需要的特判:

    当$pmid k$且$pmid a$,方程恒成立,不与原方程合并

    当$pmid k$且$p mid a$,方程恒不成立,判断无解

    解方程时不满足裴蜀定理,判断无解

    答案需要满足$xgeqlceilfrac a k ceil$

    #include<iostream>
    #include<cstdio>
    #include<cmath>
    #include<set>
    using namespace std;
    long long T,n,m,a[100005],p[100005],b[100005],maxx,c,G,x,y;
    multiset<long long>s;
    inline long long read()
    {
        long long w=0,f=1;
        char ch=0;
        while(ch<'0'||ch>'9'){if(ch=='-') f=-1; ch=getchar();}
        while(ch>='0'&&ch<='9')w=(w<<1)+(w<<3)+ch-'0',ch=getchar();
        return w*f;
    }
    void exgcd(long long a,long long b)
    {
        if(!b)
        {
            G=a,x=1,y=0;return;
        }
        exgcd(b,a%b);
        int t=x;
        x=y,y=t-a/b*y;
    }
    long long mul(long long a,long long k,long long mod)
    {
        long long ret=0;
        while(k)
        {
            if(k&1) (ret+=a)%=mod;
            (a<<=1)%=mod,k>>=1;
        }
        return ret;
    }
    int main()
    {
        T=read();
        loop:for(;T;T--)
        {
            n=read(),m=read(),s.clear();
            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++) b[i]=read();
            for(int i=1;i<=m;i++) s.insert(read());
            m=1,maxx=c=0;
            for(int i=1;i<=n;i++)
            {
                set<long long>::iterator it=s.upper_bound(a[i]);
                if(it!=s.begin()) --it;
                long long k=*it;
                s.erase(it),s.insert(b[i]),maxx=max(1.0*maxx,ceil((double)a[i]/(double)k));
                k%=p[i],a[i]%=p[i];
                if(!k&&a[i])
                {
                    puts("-1"),T--;goto loop;
                }
                if(!k&&!a[i]) continue;
                exgcd(k,p[i]);
                if(a[i]%G)
                {
                    puts("-1"),T--;goto loop;
                }
                p[i]/=G,a[i]=mul(a[i]/G,(x%p[i]+p[i])%p[i],p[i]);
                exgcd(m,p[i]);
                if((a[i]-c)%G)
                {
                    puts("-1"),T--;goto loop;
                }
                m=m/G*p[i],(c+=mul(mul(m/p[i],((a[i]-c)%m+m)%m,m),(x%m+m)%m,m))%=m;
            }
            printf("%lld
    ",c>=maxx?c:c+m*((maxx-c-1)/m+1));
        }
        return 0;
    }
    [NOI2018]屠龙勇士
  • 相关阅读:
    7. Scrapy的高级用法
    6. Scrapy的基本用法
    5. 基于Selenium实现爬虫
    4. 异步爬虫
    3. 数据解析
    2. requests的使用
    1. 爬虫概述
    03-Servlet初识
    Flask框架基础(1)
    登录mysql时,报错ERROR 2003 (HY000): Can't connect to MySQL server on 'localhost' (10061)
  • 原文地址:https://www.cnblogs.com/JDFZ-ZZ/p/14166333.html
Copyright © 2020-2023  润新知