首页 > 其他分享 >ARC125F Tree Degree Subset Sum

ARC125F Tree Degree Subset Sum

时间:2023-07-23 17:22:43浏览次数:34  
标签:Subset le limits int Sum namespace ch ARC125F sum

感觉挺不错的一道题,不过课上 pb 好像没有讲。

显然树的具体形态对题目影响不大,那么我们知道 \(\sum\limits_{i=1}^nd_i=2n-2\) 即可扔掉树的条件。即:

给定 \(n\) 个 \(d_i\),和为 \(2n-2\),求 \((x,y)\) 满足 \(0\le x\le n\) 且 \(\exists S\subseteq \{1,2,\cdots n\},|S|=x,\sum\limits_{i\in S}d_i=y\) 的数量。

我们考虑如何解决这个问题。首先可以将所有 \(d_i\) 减去 \(1\),那么 \(\sum\limits_{i=1}^nd_i=n-2\)。然后我们考虑证明,对于任意的 \(y\),设 \(m(y)\) 和 \(M(y)\) 为最小和最大的 \(x\) 使得 \((x,y)\) 合法,那么有 \(\forall i\in [m(y),M(y)]\),\((i,y)\) 合法:

  • 设 \(x(S)=|S|,y(S)=\sum\limits_{i\in S}d_i\)。
  • 我们设 \(d_i=0\) 的 \(i\) 的个数为 \(z\),由于 \(m(y)\) 的方案中没有选 \(d_i=0\) ,\(M(y)\) 的方案中一定选了 \(z\) 个 \(d_i=0\),所以只需要证明 \(M(y)-m(y)\le 2z+1\) 即可通过调整 \(0\) 的个数构造出 \(x\in [m(y),M(y)]\)。
  • 由于对于每个集合 \(S\in \{1,2,\cdots n\}\),\(-z\le y(S)-x(S)\le z-2\)(左边全取 \(0\),右边全取非 \(0\)),所以对于任意的 \(y\),\(-z\le y-M(y)\le y-m(y)\le z-2\),解不等式即可得到 \(M(y)-m(y)\le 2z-2\)。

考虑得到了 \(\forall i\in [m(y),M(y)]\),\((i,y)\) 合法这个结论,如何求出方案数。由于 \(y\le n-2\),考虑处理出对于每个 \(y\),\(M(y)\) 和 \(m(y)\) 的值,然后对 \(M(y)-m(y)+1\) 求和就是答案。

注意到 \(d\) 的总和为 \(n-2\),显然 \(d_i\) 中非 \(0\) 的互不相同的数至多只有 \(O(\sqrt n)\) 个,不难想到用单调队列优化多重背包。具体地,以 \(M(y)\) 为例,设 \(c_i=\sum\limits_{j=1}^n[d_j=i]\),\(f_{i,j}\) 表示考虑了 \(1\) 到 \(i\) 中的所有 \(d_k=i\),当前 \(y(S)\) 为 \(j\) 的方案数。那么:

\[f_{i,j}\gets \max\limits_{k=0}^{c_i}(f_{i-1,j-ki}+k) \]

套路地将 \(j\) 拆成 \(xi+y\),且 \(0\le y<i\),设 \(g_{y,x}=f_{i,xi+y}\),\(g'_{y,x}=f_{i-1,xi+y}\):

\[\begin{aligned}g_{y,x}&=\max\limits_{k=0}^{c_i}(g'_{y,x-k}+k)\\&=\max\limits_{k=0}^{c_i}(g'_{y,x-k}-(x-k))+x\end{aligned} \]

这就是经典的单调队列优化的形式了。考虑外层枚举 \(y\le i\),内层 \(x\le \left\lfloor\dfrac{n}{i}\right\rfloor\),物品数量为 \(O(\sqrt n)\),总复杂度是 \(n\sqrt n\) 的。

最后统计答案需要将 \(d_i=0\) 的贡献算上。

// Problem: F - Tree Degree Subset Sum
// Contest: AtCoder - AtCoder Regular Contest 125
// URL: https://atcoder.jp/contests/arc125/tasks/arc125_f
// Memory Limit: 1024 MB
// Time Limit: 6000 ms
// 
// Powered by CP Editor (https://cpeditor.org)

#include <bits/stdc++.h>
#define int long long
using namespace std;

namespace vbzIO {
    char ibuf[(1 << 20) + 1], *iS, *iT;
    #if ONLINE_JUDGE
    #define gh() (iS == iT ? iT = (iS = ibuf) + fread(ibuf, 1, (1 << 20) + 1, stdin), (iS == iT ? EOF : *iS++) : *iS++)
    #else
    #define gh() getchar()
    #endif
    #define mt make_tuple
    #define mp make_pair
    #define fi first
    #define se second
    #define pc putchar
    #define pb emplace_back
    #define ins insert
    #define era erase
    typedef tuple<int, int, int> tu3;
    typedef pair<int, int> pi;
    inline int rd() {
        char ch = gh();
        int x = 0;
        bool t = 0;
        while (ch < '0' || ch > '9') t |= ch == '-', ch = gh();
        while (ch >= '0' && ch <= '9') x = (x << 1) + (x << 3) + (ch ^ 48), ch = gh();
        return t ? ~(x - 1) : x;
    }
    inline void wr(int x) {
        if (x < 0) x = ~(x - 1), putchar('-');
        if (x > 9) wr(x / 10);
        putchar(x % 10 + '0');
    }
}
using namespace vbzIO;

const int N = 2e5 + 200;
const int inf = 0x3f3f3f3f;
int n, ct, hd, tl, q[N], d[N], c[N], L[N], R[N], f[N], g[N];

int w(int x) { return g[x] - x; }

signed main() {
    n = rd();
    for (int i = 1, u, v; i <= n - 1; i++)
    	u = rd(), v = rd(), d[u]++, d[v]++;
    for (int i = 1; i <= n; i++) 
    	d[i]--, ct += (!d[i]), c[d[i]]++;
    memset(R, -inf, sizeof(R));
    memset(L, inf, sizeof(L));
    L[0] = R[0] = 0;
    for (int i = 1; i <= n; i++) {
    	if (!c[i]) continue;
    	for (int y = 0; y < i; y++) {
    		for (int x = 0; x <= n / i; x++) 
    			g[x] = R[x * i + y], f[x] = -inf;
    		hd = 1, tl = 0;
    		for (int x = 0; x <= n / i; x++) {
    			while (hd <= tl && q[hd] < x - c[i]) hd++;
    			while (hd <= tl && w(q[tl]) <= w(x)) tl--;
    			q[++tl] = x;
    			f[x] = w(q[hd]) + x;
    			R[x * i + y] = max(R[x * i + y], f[x]);
    		}
    	}
    }
    for (int i = 1; i <= n; i++) {
    	if (!c[i]) continue;
    	for (int y = 0; y < i; y++) {
    		for (int x = 0; x <= n / i; x++) 
    			g[x] = L[x * i + y], f[x] = inf;
    		hd = 1, tl = 0;
    		for (int x = 0; x <= n / i; x++) {
    			while (hd <= tl && q[hd] < x - c[i]) hd++;
    			while (hd <= tl && w(q[tl]) >= w(x)) tl--;
    			q[++tl] = x;
    			f[x] = w(q[hd]) + x;
    			L[x * i + y] = min(L[x * i + y], f[x]);
    		}
    	}
    }
    int res = 0;
    for (int i = 0; i <= n; i++)
    	if (L[i] <= R[i]) res += R[i] - L[i] + 1 + ct;
	wr(res);
    return 0;
}

标签:Subset,le,limits,int,Sum,namespace,ch,ARC125F,sum
From: https://www.cnblogs.com/Ender32k/p/17575284.html

相关文章

  • 2023.07.21 SMU Summer 2023 Contest Round 5
    2023.07.21SMUSummer2023ContestRound5A.PointsinSegments给n个,1~m的子集,求1~n中所有没在这些子集中出现过的数字把子集区间合并为集合s,输出1~n中没有在s中出现过的数#include"bits/stdc++.h"usingnamespacestd;typedefpair<int,int>PII;intn,m;vector<P......
  • SMU Summer 2023 Contest Round 5
    SMUSummer2023ContestRound5A.PointsinSegments\(\mathcal{O}(n\timesm)\)做法数据范围小,直接把每次的\(l-r\)跑一遍标记一下,最后跑一遍循环统计哪些没有被标记的并且输出就好了#include<bits/stdc++.h>#defineintlonglongusingnamespacestd;signed......
  • 【项目实战】Kafka 重平衡 Consumer Group Rebalance 机制
    ......
  • LG4868 Preprefix sum 题解
    壹、题目大意给出长度为\(n\)的序列\(a_1\sima_n\),设\(S_i=\sum\limits_{j=1}^ia_j\),有两种操作可以给定\(i\)和\(x\),使得\(a_i=x\),也可以给定\(i\),查询\(\sum\limits_{j=1}^iS_j\)的值\(n\le100000\)贰、思路这道题查询的是\(S\),但实际上是\(a\),而操......
  • Python中的怎么引进SUM函数
    在Python中,我们可以使用内置的sum()函数来计算序列中所有元素的总和。sum()函数接受一个可迭代对象作为参数,并返回其元素的总和。下面是一个示例代码,展示了如何使用sum()函数来计算列表中所有元素的总和:numbers=[1,2,3,4,5]total=sum(numbers)print("总和为:",total)......
  • Sum of (-1)^f(n)
    煎蛋提。不妨令\(g(i)=(-1)^{f(i)}\),由\(f(i)\)的和性不难推出\(g(i)\)为完全积性函数,因此可以考虑杜教筛。考察\(g(n)\)和恒等函数\(I(n)=1\)的卷积\(g*I\),不难发现\((g*I)(p^k)=\sum\limits_{i=0}^kg(p^i)=\sum\limits_{i=0}^k(-1)^i=[2\midi]\),又由于\(g*I\)为......
  • ARC145F Modulo Sum of Increasing Sequences
    为数不多不用多项式科技的单位根反演题。\(A\)不降比较难搞,所以首先令\(B_i=A_i+i-1\),则\(B\)单调递增。转化为对任意的\(k\in[0,\text{MOD}-1]\),求在\([0,N+M-1]\)中选\(N\)个不同的数,总和对\(\text{MOD}\)取模为\(k\)的方案数。记\(p=\text{MOD},n=N+M\)。列出......
  • sum
    sum计算文件的校验码和显示块数补充说明sum命令用于计算并显示指定文件的校验和与文件所占用的磁盘块数。语法sum(选项)(参数)选项-r:使用BSD的校验和算法,块大小为1k;-s:使用systemV的校验和算法,块大小为512字节。参数文件列表:需要计算和与磁盘块数的文件列表。实例......
  • Atcoder Grand Contest 057 D - Sum Avoidance
    先来找些性质:\(A\)中最小的元素\(M\)肯定是最小的不是\(S\)的因子的数,由于\(\text{lcm}(1,2,3,\cdots,43)>10^{18}\),所以\(M\le43\)。对于每个\(0\lei<M\),\(\bmodM=i\)的数被选择的部分必然是一段后缀,因为如果你选择了\(M\)选择了某个\(\bmodM=i\)的数\(v\),......
  • EXCEL的SUMIF公式
    我通过简单的案例来做演示SUMIF(参数1,参数2,参数3)    图1为sheet1                                  图2为sheet2该案例如果要计算图一中各个订单号下的数量总和参数1:需要被匹配的数据源参数2:......