zoukankan      html  css  js  c++  java
  • [ABC160] 题解

    由于是ABC, 所以ABC题过于简单就咕咕咕了

    D Line++

    枚举一下所有组判断一下即可

    #include<bits/stdc++.h>
    
    using namespace std;
    
    int n, x, y, ans[10005];
    
    int main()
    {
    	cin >> n >> x >> y;
    	for(int i = 1; i <= n; i++)
    	{
    		for(int j = i + 1; j <= n; j++)
    		{
    			int t = min(min(j - i, abs(x - i) + abs(j - x)), min(abs(y - i) + abs(j - y), abs(x - i) + 1 + abs(j - y)));
    			ans[t]++;
    		}
    	}
    	for(int i = 1; i <= n - 1; i++)
    		printf("%d
    ", ans[i]);
    	return 0;
    }
    

    E Red and Green Apples

    显然从大到小排好序后最优,无色的苹果不用管它,因为只要你取到个数且不超过限制一定可以通过分配使他满足。(所以代码特别好写)

    #include<bits/stdc++.h>
    
    using namespace std;
    
    #define N 500005
    
    int a, b, c, n, X, Y;
    
    long long ans = 0;
    
    struct point
    {
    	int v, id;
    
    	bool operator < (const point &o) const
    	{
    		return v > o.v;
    	}
    }p[N];
    
    int main()
    {
    	ios::sync_with_stdio(false);
    	cin >> X >> Y >> a >> b >> c;
    	n = a + b + c;
    	for(int i = 1; i <= n; i++)
    	{
    		cin >> p[i].v;
    		if(i <= a) p[i].id = 1;
    		else if(i <= a + b) p[i].id = 2;
    		else p[i].id = 3; 
    	}
    	sort(p + 1, p + n + 1);
    	int x = 0, y = 0, cnt = 0;
    	for(int i = 1; i <= n; i++)
    	{
    		if(p[i].id == 1)
    		{
    			if(x == X) continue;
    			else x++;
    		}
    		else if(p[i].id == 2)
    		{
    			if(y == Y) continue;
    			else y++;
    		}
    		ans += 1ll * p[i].v;
    		cnt++;
    		if(cnt == X + Y) break;
    	}
    	cout << ans << endl;
    	return 0;
    }
    

    F Distributing Integers

    来填坑了

    赛时没切掉 /kk 我发现我并不会多重集的排列这个东西。

    简单介绍一下,令 (S)(k) 种不同类型对象(每种集合里的对象等价)的多重集合,从S中取r个数构成排列的方案数称为 (S)(r) 排列。当 (r = n) 时,有
    (P(n, n_1*a_1, ..., n_k*a_k) = frac{(n - 1)!}{prod_{i = 1}^{k}n_k!})

    回到这道题,我们首先取1为根,做一遍树形dp, 令 (f[i]) 表示以i为根的树有多少种填数字的方案。

    [f[x] = egin{cases} frac{(sz[x] - 1)!}{prod_{i in{ch(x)}}{sz[i]!}} imes prod_{i in{ch(x)}}{f[i]} , sz[x] > 1 \ 1, sz[x] = 1 end{cases} ]

    是叶子结点就是1, 不是叶子结点就是我把每个子树看做一个集合做多重集排列(得出顺序), 然后直接乘每个每个子树的贡献就行。

    做完第一次树形dp之后进行换根dp,这一步应该比较简单,只要每次换的时候消除/加入影响即可

    #include<bits/stdc++.h>
    
    using namespace std;
    
    #define N 200005
    const int mod = 1e9 + 7;
    #define add(x, y) (x + y >= mod ? x + y - mod : x + y)
    #define dec(x, y) (x < y ? x - y + mod ? x - y)
    
    int n, a[N], head[N], nxt[N << 1], to[N << 1], cnt = 0, sz[N], f[N], fac[N], inv[N], g[N];
    
    int Pow(int x, int k)
    {
    	int base = x, ans = 1;
    	while(k)
    	{
    		if(k & 1) ans = 1ll * ans * base % mod;
    		base = 1ll * base * base % mod;
    		k >>= 1;
    	}
    	return ans;
    }
    
    void adde(int x, int y)
    {
    	cnt++;
    	to[cnt] = y;
    	nxt[cnt] = head[x];
    	head[x] = cnt;
    }
    
    void dfs(int x, int fa)
    {
    	sz[x] = 1;
    	for(int p = head[x]; p; p = nxt[p])
    	{
    		int v = to[p];
    		if(v == fa) continue;
    		dfs(v, x);
    		sz[x] += sz[v];
    	}
    	f[x] = fac[sz[x] - 1];
    	for(int p = head[x]; p; p = nxt[p])
    	{
    		int v = to[p];
    		if(v == fa) continue;
    		f[x] = 1ll * f[x] * inv[sz[v]] % mod * f[v] % mod; 
    	}
    }
    
    void dfs2(int x, int fa)
    {
    	for(int p = head[x]; p; p = nxt[p])
    	{
    		int v = to[p];
    		if(v == fa) continue;
    		int t = 1ll * g[x] * fac[n - 1 - sz[v]] % mod * inv[n - 1] % mod * fac[sz[v]] % mod * Pow(f[v], mod - 2) % mod;
    		int ns = n - sz[v];
    		// cout << x << ' ' << v << ' ' << t << ' ' << ns << endl;
    		g[v] = 1ll * f[v] * t % mod * inv[ns] % mod * fac[n - 1] % mod * inv[sz[v] - 1] % mod;
    		dfs2(v, x);
    	}
    }
    
    int main()
    {
    	scanf("%d", &n);
    	for(int i = 1; i <= n - 1; i++)
    	{
    		int x, y;
    		scanf("%d%d", &x, &y);
    		adde(x, y), adde(y, x);
    	}
    	fac[0] = 1, inv[0] = 1, fac[1] = 1, inv[1] = 1;
    	for(int i = 2; i <= n; i++) fac[i] = 1ll * fac[i - 1] * i % mod, inv[i] = Pow(fac[i], mod - 2);
    	dfs(1, 1);
    	// cout << f[1] << endl;
    	g[1] = f[1];
    	dfs2(1, 1);
    	for(int i = 1; i <= n; i++)
    		printf("%d
    ", g[i]);
    	return 0;
    }
    
  • 相关阅读:
    leetcode5 Longest Palindromic Substring
    leetcode17 Letter Combinations of a Phone Number
    leetcode13 Roman to Integer
    leetcode14 Longest Common Prefix
    leetcode20 Valid Parentheses
    leetcode392 Is Subsequence
    leetcode121 Best Time to Buy and Sell Stock
    leetcode198 House Robber
    leetcode746 Min Cost Climbing Stairs
    tomcat下使用druid配置jnid数据源
  • 原文地址:https://www.cnblogs.com/LJB00131/p/12590040.html
Copyright © 2011-2022 走看看