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;
    }
    
  • 相关阅读:
    在Centos 7下编译openwrt+njit-client
    开博随笔
    Chapter 6. Statements
    Chapter 4. Arrays and Pointers
    Chapter 3. Library Types
    Chapter 2.  Variables and Basic Types
    关于stm32不常用的中断,如何添加, 比如timer10 timer11等
    keil 报错 expected an identifier
    案例分析 串口的地不要接到电源上 会烧掉
    案例分析 CAN OPEN 调试记录 进度
  • 原文地址:https://www.cnblogs.com/LJB00131/p/12590040.html
Copyright © 2011-2022 走看看