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

    题目描述

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

    游戏的目标是按照编号1~n 顺序杀掉n 条巨龙,每条巨龙拥有一个初始的生命 值ai 。同时每条巨龙拥有恢复能力,当其使用恢复能力时,它的生命值就会每 次增加 pi ,直至生命值非负。只有在攻击结束后且当生命值恰. 好. 为 0 时它才会 死去。

    游戏开始时玩家拥有m 把攻击力已知的剑,每次面对巨龙时,玩家只能选择一 把剑,当杀死巨龙后这把剑就会消失,但作为奖励,玩家会获得全新的一把剑。 小D 觉得这款游戏十分无聊,但最快通关的玩家可以获得ION2018 的参赛资格, 于是小D 决定写一个笨笨的机器人帮她通关这款游戏,她写的机器人遵循以下规则:

    每次面对巨龙时,机器人会选择当前拥有的,攻击力不高于巨龙初始生命值中攻击力最大的一把剑作为武器。如果没有这样的剑,则选择攻. 击. 力. 最. 低. 的一把剑作为武器。

    机器人面对每条巨龙,它都会使用上一步中选择的剑攻击巨龙固. 定. 的. x 次,使巨龙的生命值减少 x×ATKx \times ATKx×ATK 。

    之后,巨龙会不断使用恢复能力,每次恢复pi 生命值。若在使用恢复能力前或 某一次恢复后其生命值为0 ,则巨龙死亡,玩家通过本关。

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

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

    输入输出格式

    输入格式:

    从文件dragon.in 中读入数据。

    第一行一个整数T ,代表数据组数。

    接下来T 组数据,每组数据包含5 行。

    每组数据的第一行包含两个整数,n 和m ,代表巨龙的数量和初始剑的数量;
    
    接下来一行包含n 个正整数,第i 个数表示第i 条巨龙的初始生命值ai ;
    
    接下来一行包含n 个正整数,第i 个数表示第i 条巨龙的恢复能力pi ;
    
    接下来一行包含n 个正整数,第i 个数表示杀死第i 条巨龙后奖励的剑的攻击力;
    
    接下来一行包含m 个正整数,表示初始拥有的m 把剑的攻击力。
    

    输出格式:

    输出到文件dragon.out 中。 一共T 行。

    第i 行一个整数,表示对于第i 组数据,能够使得机器人通关游戏的最小攻击次数x ,如果答案不存在,输出-1。


    题解

    1. x和p不互质,不能求逆元???所以直接用带参数的同余方程 $$b_ix\equiv a_i\mod p_i$$ 令\(g=gcd(b_i,p_i),x_0\)为该方程的一个特解,则最后\(x_0\)一定要模\(p_i/g\)而不是直接模\(p_i\)
    2. 数据范围是\(10^{12}\)直接用\(long\ long\)的话,中间结果可能会爆炸,所以要拆开来乘。
    3. 注意取最小正整数
    #include<bits/stdc++.h>
    #define REP(i,a,b) for(int i=(a);i<=(b);++i)
    #define DEC(i,a,b) for(int i=(a);i>=(b);--i)
    #define dbg(...) fprintf(stderr,__VA_ARGS__)
    using namespace std;
    template<typename T,typename U> inline bool smax(T&x,const U&y){return y>x?(x=y,1):0;}
    template<typename T,typename U> inline bool smin(T&x,const U&y){return y<x?(x=y,1):0;}
    typedef long long ll;
    typedef pair<int,int> pii;
    #define pb push_back
    #define X first
    #define Y second
    template<typename T>
    inline void rd(T&w){
        char c;
        while(!isdigit(c=getchar()));w=c-48;
        while(isdigit(c=getchar()))w=w*10+c-48;
    }
    const int N=2e5+5;
    int n,m;
    ll a[N],p[N],b[N],minx,tmp;
    inline ll mul(ll x,ll y,ll p){
    	if(x>=p)x%=p;if(y>=p)y%=p;
    	if(x<=1e9&&y<=1e9)return x*y%p;
    	ll ans=0,tmp;
    	while(y){
    		if(tmp=y%10000)ans=(ans+x*tmp%p)%p;
    		x=x*10000%p;y/=10000;
    	}
    	return ans;
    }
    inline ll gcd(ll a,ll b,ll&x,ll&y){
    	if(!b)return x=1,y=0,a;
    	ll d=gcd(b,a%b,y,x);y-=a/b*x;
    	return d;
    }
    inline void write(ll x){
    	static char st[25];
    	int top=0;
    	while(x)st[++top]=x%10+'0',x/=10;
    	while(top)putchar(st[top--]);
    	putchar('\n');
    }
    multiset<ll> s;
    multiset<ll>::iterator it;
    int main(){
    //	freopen("dragon.in","r",stdin);
    //	freopen("dragon.out","w",stdout);
    	int T;rd(T);
    	while(T--){
    		rd(n),rd(m);s.clear();minx=0;
    		REP(i,1,n)rd(a[i]);
    		REP(i,1,n)rd(p[i]);
    		REP(i,1,n)rd(b[i]);
    		REP(i,1,m)rd(tmp),s.insert(tmp);
    		ll x,y;
    		REP(i,1,n){
    			it=s.upper_bound(a[i]);if(it!=s.begin())--it;
    			smax(minx,(a[i]-1)/(*it)+1);a[i]%=p[i];
    			s.insert(b[i]);
    			b[i]=*it;
    			s.erase(it);
    		}
    		ll g=gcd(b[1],p[1],x,y),k,now;
    		bool f=1;
    		if(a[1]%g)f=0;else now=mul(a[1]/g,x,k=p[1]/g);
    		if(f)REP(i,2,n){
    			ll&m=p[i];
    			g=gcd(k%m*b[i]%m,m,x,y);
    			a[i]=(a[i]-b[i]*now%m+m)%m;
    			if(a[i]%g){f=0;break;}
    			tmp=m/g;x=mul(a[i]/g,x,tmp);
    			now+=x*k;k*=tmp;
    			now=(now%k+k)%k;
    		}
    		
    		if(f){
    			now=minx/k*k+now;
    			write(now>=minx?now:now+k);
    		}else puts("-1");
    	}
    	return 0;
    }
    
    
    
  • 相关阅读:

    20145309《网络对抗》网络欺诈技术防范
    ceshi
    20145306 网路攻防 web安全基础实践
    20145306 张文锦 网络攻防 web基础
    20145306张文锦 网络欺诈技术防范
    20145306 《网络攻防》 信息搜集与漏洞扫描
    20145306 《网络攻防》 MSF基础应用
    20145306张文锦《网络对抗》恶意代码分析
    20145306 《网络攻防》 免杀技术
  • 原文地址:https://www.cnblogs.com/HolyK/p/9830245.html
Copyright © 2011-2022 走看看