• NOI2018D2T1 屠龙勇士


    安利一下松松松的OJ: 传送门

    Description:

    ​ 有N条巨龙, 对于每个龙含有(a_i)的生命, 你有N + M把砍刀, 其中M把是直接给你的, N把是杀死对应的巨龙才能获得的, 每把砍刀除攻击外没有区别,记为(b_i), 每个巨龙一旦血量被砍到0即为死亡, 低于零则每秒回复(p_i)的血量, 现在要求你攻击每个巨龙X次, 求X的最小值或判无解.对于剑的选择, 参见具体题目.

    Analysis & Solution:

    ​ 考虑每条龙死亡的条件:
    $ A_i + P_i * k = X * b_i( ) X * b_i equiv A_i pmod{P_i}( ) X equiv A_i * b_i^{-1} pmod{P_i}$

    ​ 这样就得到了关于(X)的一系列同余方程.

    ​ 可以用ExCRT求解.

    ExCRT:

    		> ​		关于求解多组同余组最小整数解的模数非互质情况的算法
    

    [
    ​ 然后就把两个方程合并成了一个方程, 这样就可以在(O(nlogn)) 内求出同余方程组的最小整数解.

    然后本题目就可以在(O(nlogn))内求出解, 注意取模时候用快速乘或int128, 然而€€£并不能用int128.

    Code:

    #include<bits/stdc++.h>
    #define rep(i, a, b) for(int i = (a), i##_end_ = (b); i <= i##_end_; ++i)
    #define drep(i, a, b) for(int i = (a), i##_end_ = (b); i >= i##_end_; --i)
    #define clar(a, b) memset((a), (b), sizeof(a))
    using namespace std;
    typedef long long LL;
    typedef long double LD;
    LL read() {
        LL x = 0, flag = 1;
        char ch = getchar();
        while(!isdigit(ch)) {
            if(ch == '-') flag *= -1;
            ch = getchar();
        }
        while(isdigit(ch)) {
            x = (x << 3) + (x << 1) + (ch - 48);
            ch = getchar();
        }
        return x * flag;
    }
    void write(LL a) {
    	if(a >= 10) write(a / 10);
    	putchar(a % 10 + '0');
    } 
    
    #define Maxn 100009
    multiset <LL> Set;
    LL a[Maxn], p[Maxn], l[Maxn], z[Maxn], sword[Maxn], csf[Maxn][3];
    int n, m;
    void refresh_mem() {
    	clar(a, 0), clar(p, 0), clar(l, 0), clar(z, 0), clar(csf, 0);
    	clar(sword, 0);
    }
    LL qmul(LL x, LL y, LL mod) {
        LL ret = 0;
        while(y) {
            if(y & 1) ret = (ret + x) % mod;
    		(x <<= 1) %= mod, y >>= 1;
        }
        return ret;
    }
    LL Extend_Euclid(LL a,LL b,LL &x,LL &y){
        if(!b){
            x = 1, y = 0; 
    		return a;
        }
        LL d = Extend_Euclid(b, a % b, x, y), t = x;
        x = y; y = t - a / b * y;
        return d;
    }
    LL gcd(LL a, LL b) { return b ? gcd(b, a % b) : a; }
    LL inv(LL a, LL b){
        LL x, y; LL t = Extend_Euclid(a, b, x, y);  
        if(t != 1) return -1;
        return (x % b + b) % b;
    }
    int merge(LL &a1, LL &n1, LL a2, LL n2) {
    	LL d = gcd(n1, n2), c = a2 - a1, tmp1, tmp2;
    	if(c % d != 0) return 0;
    	c = (c % n2 + n2) % n2 / d;
    	n1 /= d, n2 /= d;
    	c = ((__int128)c) * inv(n1, n2) % n2;
    	tmp2 = n1 * n2 * d;
    	c = ((((__int128)c) * n1 % tmp2 * d % tmp2) + a1) % tmp2;
    	tmp1 = (c + tmp2) % tmp2;	
    	a1 = tmp1, n1 = tmp2;
    	return 1;
    }
    LL ExCRT(int cnt_equ) {
    	LL a1 = csf[1][1], n1 = csf[1][2]; // remainder & mod 
    	rep(i, 2, cnt_equ) if(!merge(a1, n1, csf[i][1], csf[i][2])) return -1;
    	return (a1 % n1 + n1) % n1;
    }
    void solve() { cout << ExCRT(n) << endl; }
    int main() {
    	int T = read();
    	while(T--) {
    		refresh_mem();
    		LL LM = -1;
    		n = read(), m = read();
    		Set.clear();
    		rep(i, 1, n) a[i] = read();
    		rep(i, 1, n) p[i] = read(), LM = max(LM, p[i]);
    		rep(i, 1, n) z[i] = read();
    		rep(i, 1, m) l[i] = read(), Set.insert(l[i]);
    		Set.insert((LL)1e13);
    		rep(i, 1, n) {
    			set<LL> :: iterator tmp = Set.upper_bound(a[i]);
    			if(tmp != Set.begin()) --tmp;
    			sword[i] = *tmp; Set.erase(tmp); Set.insert(z[i]);
    		}
    		if(LM == 1) {
    			LL ans = 0;	
    			rep(i, 1, n) {
    				LL tmp = a[i] / sword[i];
    				if(sword[i] * tmp < a[i]) ++tmp;
    				ans = max(ans, tmp);
    			}
    			cout << ans << endl;
    			continue;
    		}
    		int flag = 0;
    		rep(i, 1, n) {
    			LL z = gcd(gcd(a[i], p[i]), sword[i]);
    			a[i] /= z; p[i] /= z; sword[i] /= z;
    			z = inv(sword[i], p[i]);
    			if(z == -1) {
    				flag = 1;
    				break;
    			}
    			csf[i][1] = qmul(a[i], z, p[i]);
    			csf[i][2] = p[i];
    		}
    		if(!flag) solve(); else puts("-1");
    	}
    	return 0;
    }
    // -O2 
    
  • 相关阅读:
    *Convert Sorted Array to Binary Search Tree
    *Count Complete Tree Nodes
    *Binary Tree Paths
    Invert Binary Tree
    *Kth Smallest Element in a BST
    **Lowest Common Ancestor of Two Nodes in a Binary Tree
    Lowest Common Ancestor of a Binary Search Tree
    *Sum root to leaf number
    subversion javahl
    mongodb从来没有说它写成功了。
  • 原文地址:https://www.cnblogs.com/qrsikno/p/9791405.html
Copyright © 2020-2023  润新知