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

    昨天晚上快走时看了这题:不是exgcd+excrt吗?
    旁边张大佬默默看了我一眼(觉得我会死)
    然后于是我今天中午才调出来Orz


    思路:exgcd+excrt

    提交:5次

    错因:龟速乘传进去了负数,并且用的int;之前写过的excrt的板子有问题

    题解:

    先要特判一种情况:若 (p[i]=1) ,答案显然就是 (max(lceilfrac{a[i]}{stk[i]} ceil)) ,只需要把龙打成负血他就死了。

    先是这样的一些方程:设 (atk[i]) 表示对于第 (i) 只龙使用攻击力为 (atk[i]) 的剑

    [atk[i]*x_i equiv a[i] mod p[i] ]

    好的这样我们可以 exgcd 解出 (X_i=x_i*frac{a[i]}{gcd(atk[i],p[i])})
    我们知道,对于上面的方程来说,(X_i+k*frac{p[i]}{gcd(atk[i],p[i])},kin Z)
    (b[i]=frac{p[i]}{gcd(atk[i],p[i])}) ,所以对于最终答案(ans)有:

    [ansequiv X_i mod b[i] ]

    这个 (ans) 是可以用 excrt 合并的。

    代码:

    #include<bits/stdc++.h>
    #define ll long long
    #define R register int
    using namespace std;
    namespace Luitaryi {
    template<class I> inline I g(I& x) { x=0; register I f=1;
    	register char ch; while(!isdigit(ch=getchar())) f=ch=='-'?-1:f;
    	do x=x*10+(ch^48); while(isdigit(ch=getchar())); return x*=f;
    } 
    template<class I> inline I ps(I x) { if(x<0) putchar('-'),x=-x;
    	static char s[40]; register int sz=0; 
    	while(x!=0) s[++sz]=x%10,x/=10; 
    	while(sz) putchar(s[sz]+'0'),--sz;
    }
    const int N=100010;
    inline ll exgcd(ll& x,ll& y,ll a,ll b) {
    	if(!b) {x=1,y=0; return a;} 
    	register ll d=exgcd(y,x,b,a%b); y-=a/b*x; 
    	return d;
    }
    int T,n,m;
    ll s[N],b[N],c[N],a[N],mx;
    multiset<ll> ss; bool flg;
    multiset<ll>::iterator it;
    inline ll mul(ll a,ll b,ll p) { register ll ret=0; 
    	for(;b;b>>=1,a=(a+a)%p) if(b&1) ret=(ret+a)%p; 
    	ret=(ret+p)%p; return ret;
    }
    inline void main() { 
    	g(T); while(T--) { mx=0,flg=true;
        register ll ans=0,sum=1,x,y;
    		g(n),g(m); for(R i=1;i<=n;++i) g(s[i]);
    		for(R i=1;i<=n;++i) g(b[i]),flg&=b[i]==1;
    		for(R i=1;i<=n;++i) g(c[i]);
    		for(R i=1;i<=m;++i) g(x),ss.insert(x);
    		for(R i=1;i<=n;++i) {
    			it=ss.upper_bound(s[i]);
    			if(it!=ss.begin()) --it; 
    			a[i]=*it,ss.erase(it),ss.insert(c[i]);
    			mx=max((s[i]+a[i]-1)/a[i],mx);
    		} if(flg) { 
    			printf("%lld
    ",mx);
    			goto end;
    		}
    		for(R i=1;i<=n;++i) { register ll x,y;
    			register ll d=exgcd(x,y,a[i],b[i]);
    			if(s[i]%d) {puts("-1"); goto end;}
    			b[i]/=d,x=(x%b[i]+b[i])%b[i]; 
    			s[i]=mul(x,((s[i]/d)%b[i]+b[i])%b[i],b[i]);
    		}
    		for(R i=1;i<=n;++i) {
    			register ll d=exgcd(x,y,sum,b[i]);
    			if((s[i]-ans)%d) {puts("-1"); goto end;}
    			b[i]/=d; 
    			x=mul(x,((s[i]-ans)/d%b[i]+b[i])%b[i],b[i]);
    			ans+=x*sum,sum=sum*b[i];
    		} printf("%lld
    ",(ans%sum+sum)%sum);
    		end:ss.clear();
    	}
    }
    } signed main() {Luitaryi::main(); return 0;}
    

    2019.09.03
    66

  • 相关阅读:
    POJ
    归并排序+归并排序求逆序对(例题P1908)
    HDU
    2018-12-5 及 codeforces round 525v2
    2018-12-1学习纪录
    近期总结和未来规划
    C++ storage allocation + Dynamic memory allocation + setting limits + initializer list (1)
    注意项
    第四课 计算机的基本组成
    第二课+第三课 计算机系统概论
  • 原文地址:https://www.cnblogs.com/Jackpei/p/11452405.html
Copyright © 2011-2022 走看看