• Codeforces Round #678 Div. 2


    A. Reorder

    给定一串数列和m,问是否可能存在一个重排令

    [sum_{i=1}^{n}sum_{j=i}^{n}(double)a_{j}/j==m ]

    直接和是否等于m

    #include<iostream>
    #include<queue>
    #include<map>
    #include<utility>
    #include<vector>
    #include<algorithm>
    #include<cstring>
    #include<string>
    #include<stdio.h>
    #include<sstream>
    #include<fstream>
    #include<cmath>
    #include<set>
    #include<math.h>
    using namespace std;
    typedef  long long  ll;					//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    typedef pair<int, int> P;
    ll m;
    int main() {
    	cin >> m;
    	while (m--)
    	{
    		ll a, b;
    		cin >> a >> b;
    		ll ans = 0;
    		for (int i = 0; i < a; i++) {
    			ll tmp;
    			cin >> tmp;
    			ans += tmp;
    		}
    		if (ans == b)cout << "YES
    ";
    		else cout << "NO
    ";
    	}
    }
    

    B .Prime Square

    给定n,求一个n×n的矩阵,令矩阵中每个数字都不是质数,每行每列和是质数

    0,1不是质数,2,3是质数

    只要把1按X状排列,然后再把第一列的中间那个数改成1即可

    #include<iostream>
    #include<queue>
    #include<map>
    #include<utility>
    #include<vector>
    #include<algorithm>
    #include<cstring>
    #include<string>
    #include<stdio.h>
    #include<sstream>
    #include<fstream>
    #include<cmath>
    #include<set>
    #include<math.h>
    using namespace std;
    typedef  long long  ll;					//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    typedef pair<int, int> P;
    ll m;
    int main() {
    	cin >> m;
    	while (m--)
    	{
    		ll a, b;
    		cin >> a;
    		ll ans = 0;
    		for (int i = 0; i < a; i++) {
    			for (int j = 0; j < a; j++) {
    				if (i == j||i+j==a-1||(j==0&&i==a/2)|| (i == 0 && j == a / 2))cout << 1 << ' ';
    				else cout << 0 << ' ';
    			}
    			cout << '
    ';
    		}
    	}
    }
    

    给定一串长度为n的数列,问有多少种排列能用二分法找到pos处的X

    我们模拟二分操作,就能知道要找出X的话,

    在什么位置需要放大于X的数,什么地方放小于X的数,然后求组合数即可

    #include<iostream>
    #include<queue>
    #include<map>
    #include<utility>
    #include<vector>
    #include<algorithm>
    #include<cstring>
    #include<string>
    #include<stdio.h>
    #include<sstream>
    #include<fstream>
    #include<cmath>
    #include<set>
    #include<math.h>
    using namespace std;
    typedef  long long  ll;					//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    typedef pair<int, int> P;
    ll n, x, pos;
    ll lm = 0, rm = 0;
    const ll mod = 1e9 + 7;
    ll inv[10000];
    ll f[10000];
    ll qpow(ll a, ll b) {
    	ll res = 1;
    	a %= mod;
    	while (b)
    	{
    		if (b & 1)res = (res * a) % mod;
    		b >>= 1;
    		a = a * a % mod;
    	}
    	return res;
    }
    void pre(ll len) {
    	f[0] = 1;
    	for (int i = 1; i <= len; i++)
    		f[i] = i * f[i - 1] % mod;
    	inv[len] = qpow(f[len], mod - 2);
    	for (int i = len - 1; i >= 0; i--)inv[i] = inv[i + 1] * (i + 1) % mod;
    }
    ll A(ll n, ll m) {
     
    	if (n < m || n < 0)return 0;
    	return f[n] % mod * inv[n - m] % mod;
    }
    int main() {
    	cin >> n >> x >> pos;
    	ll l = 0, r = n, mid = -1;
    	pre(1000 + 5);
    	ll ans = 1;
    	while (1)
    	{
    		mid = (l + r) / 2;
    		if (mid == pos) {
    			l = mid + 1; break;
    		}
    		else if (mid > pos) lm++, r = mid;
    		else rm++, l = mid + 1;
    	}
    	while (l<r)
    	{
    		r = (l + r) / 2;
    		lm++;
    	}
    	ans = A(n - x, lm) * A(x - 1, rm) % mod * A(n - lm - rm - 1, n - lm - rm - 1) % mod;
    		
    	cout << ans;
    }
    

    D. Bandit in a City

    给定一个树和每个点的人数,某时刻根出现强盗,每次行动强盗和所有人都要选其中一个子树走,

    最终强盗所在的叶子的人数最小值是多少 强盗和人都倾向于最优解

    考虑强盗到达某一节点,如果强盗下到其中一个子节点,其他人就应该都跑到其他节点为最优状况,

    所以强盗抓到人数的最好情况是以当前节点为根的子树的和/当前子树的叶子数,

    但是不一定能够均匀分配,所以求所有的sum[u]/lev[u]的最值

    #include<iostream>
    #include<queue>
    #include<map>
    #include<utility>
    #include<vector>
    #include<algorithm>
    #include<cstring>
    #include<string>
    #include<stdio.h>
    #include<sstream>
    #include<fstream>
    #include<cmath>
    #include<set>
    #include<math.h>
    using namespace std;
    typedef  long long  ll;					//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    typedef pair<int, int> P;
    ll n, m, pos;
    ll lm = 0, rm = 0;
    const ll mod = 998244353;
    ll dat[300000+5];
    vector<ll>s[300000 + 5];
    const int maxn = 100005;
    ll son[300000 + 5];
    ll val[300000 + 5];
    ll dfs(ll x) {
        if (s[x].size() == 0||val[x])return val[x]=dat[x];
        ll ans = dat[x];
        for (int i = 0; i < s[x].size(); i++) {
            ans += dfs(s[x][i]);
        }
        return val[x] = ans;
    }
    ll dfs2(ll x) {
        if (s[x].size() == 0 || son[x] != 0)return son[x]=1;
        ll ans = son[x];
        for (int i = 0; i < s[x].size(); i++) {
            ans += dfs2(s[x][i]);
        }
        return son[x] = ans;
    }
    ll cal(ll x) {
        ll ans = -1;
        for (int i = 1; i <= n; i++) {
            ans = max(ans,(val[i]+son[i]-1) / son[i]);
       }
        return ans;
    }
    int main() {
        cin >> n;
        for (int i = 2; i <= n; i++) {
            ll tmp;
            cin >> tmp;
            s[tmp].push_back(i);
        }
        for (int i = 1; i <= n; i++)cin >> dat[i];
        dfs(1);
        dfs2(1);
        ll ans = cal(1);
        cout << ans;
    }
     
    

    E. Complicated Computations

    规定数列的MEX为数列中第一个没有出现的数,求给定数列MEX的MEX

    由给定的每个数都小于等于n,想到从1到n枚举,看是否可以是MEX,最后求总的MEX

    考虑数字a,如果在两个a的间隔(或者开头到第一个a,最后一个a到结尾)中1到a-1都出现了,那么a就可以当作MEX,

    按顺序更新,

    令上次a出现的位置为lst[a],当前a的位置是i,只要求1到a-1出现的位置的最小值都大于lst[a]那么他们就都出现了,

    a就可以作为MEX的值,后更新lst[a]即可

    1要特判

    #include<iostream>
    #include<queue>
    #include<map>
    #include<utility>
    #include<vector>
    #include<algorithm>
    #include<cstring>
    #include<string>
    #include<stdio.h>
    #include<sstream>
    #include<fstream>
    #include<cmath>
    #include<set>
    #include<math.h>
    using namespace std;
    typedef  long long  ll;					//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    ll vis[100000 + 5];
    ll dat[100000 + 5];
    ll val[100001 << 2];
    ll lst[100000 + 5];
    ll n;
    void updata(ll o, ll l, ll r, ll pos, ll n) {
        if (l == r)return (void)(val[o] = n);
        ll mid = (l + r) / 2;
        if (mid >= pos)updata(o << 1, l, mid, pos, n);
        else updata(o << 1 | 1, mid + 1, r, pos, n);
        val[o] = min(val[o << 1], val[o << 1 | 1]);
    }
    ll q(ll o, ll l, ll r, ll L, ll R) {
        if (l >= L && r <= R) {
            return val[o];
        }
        else {
            ll ans = 1000000;
            ll mid = l + (r - l)/2;
            if (L <= mid)ans=min(ans,q(o << 1, l,mid, L, R));
            if (R > mid)ans = min(ans, q(o << 1 | 1, mid + 1, r, L, R));
            return ans;
        }
    }
    int main() {
        cin >> n;
        for (int i = 1; i <= n; i++)cin >> dat[i];
        for (int i = 1; i <= n; i++) {
            if (dat[i] > 1)vis[1] = 1;
            if(dat[i]>1)q(1, 1, n, 1, dat[i] - 1);
            if (dat[i] > 1 && q(1, 1, n, 1, dat[i] - 1) > lst[dat[i]])vis[dat[i]] = 1;
            lst[dat[i]] = i;
            updata(1, 1, n, dat[i], i);
        }
        for (int i = 2; i <= n + 1; i++)
            if (q(1, 1, n, 1, i - 1) > lst[i])vis[i] = 1;
        ll ans = 1;
        while (vis[ans])ans++;
        cout << ans;
        
    }
    
    
    K-ON!!
  • 相关阅读:
    teb教程1
    teb-安装
    47个项目管理过程之项目干系人管理
    47个项目管理过程之项目采购管理
    47个项目管理过程之项目风险管理
    47个项目管理过程之项目沟通管理
    47个项目管理过程之项目人力资源管理
    47个项目管理过程之项目质量管理
    47个项目管理过程之项目成本管理
    47个项目管理过程之项目时间管理
  • 原文地址:https://www.cnblogs.com/pophirasawa/p/14013648.html
Copyright © 2020-2023  润新知