• BZOJ5418:[NOI2018]屠龙勇士(exCRT,exgcd,set)


    Description

    Input

    Output

    Sample Input

    2
    3 3
    3 5 7
    4 6 10
    7 3 9
    1 9 1000
    3 2
    3 5 6
    4 8 7
    1 1 1
    1 1

    Sample Output

    59
    -1

    Solution

    当时同步赛的时候写出来了……只不过忘了是爆$long~long$还是小细节写爆了只有$75$……

    当时蠢的一比直接强上了一颗$splay$强行增加码量……现在觉得当时太蠢了然后就重写了一遍……

    首先对于这个题,每次使用的剑可以发现是固定的,这个可以使用$set$来求出来。

    知道了攻击力,知道了龙的血量和回血,就可以$exgcd$求出用多少刀的倍数砍死龙了。这其实是一个同余方程。

    把所有同余方程搞出来,然后$exCRT$求解同余方程组就完事了QAQ

    记得用快速乘还有特判一下回血全是$1$的情况。

    Code

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<set>
     4 #define N (100009)
     5 #define LL long long
     6 using namespace std;
     7 
     8 LL T,n,m,x,a[N],p[N],v[N],Ai[N],Mod[N];
     9 multiset<LL>S;
    10 
    11 LL Mul(LL a,LL b,LL MOD)
    12 {
    13     LL tmp=a*b-(LL)((long double)a*b/MOD+0.1)*MOD;
    14     return tmp<0?tmp+MOD:tmp;
    15 }
    16 
    17 void exgcd(LL a,LL b,LL &d,LL &x,LL &y)
    18 {
    19     if (!b) {d=a; x=1; y=0; return;}
    20     exgcd(b,a%b,d,y,x); y-=x*(a/b);
    21 }
    22 
    23 LL Find(LL x)
    24 {
    25     multiset<LL>::iterator it;
    26     it=S.upper_bound(x);
    27     if (it!=S.begin()) it--;
    28     LL ans=*it;
    29     S.erase(it);
    30     return ans;
    31 }
    32 
    33 LL exCRT()
    34 {
    35     LL M=Mod[1],A=Ai[1],d,x,y,t;
    36     for (int i=2; i<=n; ++i)
    37     {
    38         exgcd(M,Mod[i],d,x,y);
    39         if ((Ai[i]-A)%d) return -1;
    40         t=Mod[i]/d; x=(x%t+t)%t; x=Mul(x,(Ai[i]-A)/d,t); 
    41         A=M*x+A; M=M/d*Mod[i]; A%=M;
    42     }
    43     A=(A%M+M)%M;
    44     return A;
    45 }
    46 
    47 int main()
    48 {
    49     scanf("%lld",&T);
    50     while (T--)
    51     {
    52         S.clear();
    53         scanf("%lld%lld",&n,&m);
    54         for (int i=1; i<=n; ++i) scanf("%lld",&a[i]);
    55         for (int i=1; i<=n; ++i) scanf("%lld",&p[i]);
    56         for (int i=1; i<=n; ++i) scanf("%lld",&v[i]);
    57         for (int i=1; i<=m; ++i) scanf("%lld",&x), S.insert(x);
    58         
    59         LL maxn=-1,flag=1,all_one=1;
    60         for (int i=1; i<=n; ++i)
    61         {
    62             LL A=Find(a[i]),B=p[i],C=a[i],x,y,d;
    63             exgcd(A,B,d,x,y);
    64             if (C%d) {flag=0; break;}
    65             x=(x%B+B)%B;
    66             Ai[i]=Mul(x,C/d,B); Mod[i]=B/d;
    67             if (p[i]!=1) all_one=0;
    68             maxn=max(maxn,a[i]/A+(a[i]%A!=0));
    69             S.insert(v[i]);
    70         }
    71         
    72         if (!flag) {puts("-1"); continue;}
    73         if (all_one) printf("%lld
    ",maxn);
    74         else printf("%lld
    ",exCRT());
    75     }
    76 }
  • 相关阅读:
    为什么游戏行业喜欢用PolarDB
    以“升舱”之名,谈谈云原生数据仓库AnalyticDB的核心技术
    研发效能的思考总结
    InnoDB之UNDO LOG介绍
    数据库事务隔离发展历史
    拥抱开放,Serverless 时代的下一征程
    对软件系统的一些理解
    【20220221】数据得多维去看
    【20220222】充满爱,必然以被爱作为回报
    【一句日历】2022年3月
  • 原文地址:https://www.cnblogs.com/refun/p/10139701.html
Copyright © 2020-2023  润新知