首页 > 其他分享 >AtCoder Regular Contest 104 F Visibility Sequence

AtCoder Regular Contest 104 F Visibility Sequence

时间:2023-04-16 10:12:33浏览次数:61  
标签:AtCoder limits Contest sum Sequence 一棵树 long maxn

洛谷传送门

AtCoder 传送门

考虑连边 \((i,p_i)\)(若 \(p_i = -1\) 则不连边),可以发现形成了一篇内向树森林且这个森林存在一个 dfs 序为 \(1,2,...,n\)。

这棵森林有如下性质:

  • \(\forall v \in son_u,h_u > h_v\)
  • \(\forall v,w \in son_u \land v < w,h_v \le h_w\)

考虑一个 \(p\),我们寻找一个最优的 \(h_0\),使得它能生成 \(p\)。显然 \(h_0\) 的每个数都要取到下界。

因为一棵树的点编号为连续的区间,所以考虑区间 dp。

设 \(f_{i,j,x}\) 为 \([i,j]\) 形成了一棵树且 \(h_i = x\) 的方案数,同时设 \(g_{i,j,x}\) 为 \([i,j]\) 形成了一片森林且最后一棵树的根的 \(h\) 值 \(= x\) 的方案数。

有转移:

  • \(f_{i,j,x} \gets g_{i+1,j,x-1}\),表示以 \(i\) 为根将 \([i+1,j]\) 的森林连起来。
  • \(g_{i,j,x} \gets f_{i,j,x}\),表示一棵树也算森林。
  • \(g_{i,j,x} \gets \sum\limits_{k=i}^{j-1} [x \le a_{k+1}] \sum\limits_{t=1}^x g_{i,k,t} \times f_{k+1,j,x}\),表示枚举这片森林的最后一棵树(此时森林一定要有至少两棵树)的树根 \(k+1\),\(h_{k+1}=x\),前面的数的 \(h\) 值都要 \(\le x\)。
  • \(g_{i,j,x} \gets \sum\limits_{k=i}^{j-1} [x \le a_{k+1}]g_{i,k,x} \times \sum\limits_{t=1}^{x-1} f_{k+1,j,t}\),仍然表示枚举最后一棵树的根 \(k+1\),但是 \(h_{k+1} < x\),此时把最后一棵树的 \(h\) 值整体加直至 \(h_{k+1} = x\)。\(< x\) 是因为要避免算重。

答案即为 \(\sum\limits_{x=1}^n f_{1,n,x}\)。

直接转移是 \(O(n^5)\) 的,因此再设 \(sf_{i,j,x} = \sum\limits_{t=1}^x f_{i,j,x},sg_{i,j,x} = \sum\limits_{t=1}^x g_{i,j,x}\),这样整道题就变成 \(O(n^4)\) 了。

code
// Problem: F - Visibility Sequence
// Contest: AtCoder - AtCoder Regular Contest 104
// URL: https://atcoder.jp/contests/arc104/tasks/arc104_f
// Memory Limit: 1024 MB
// Time Limit: 2000 ms
// 
// Powered by CP Editor (https://cpeditor.org)

#include <bits/stdc++.h>
#define pb emplace_back
#define fst first
#define scd second
#define mems(a, x) memset((a), (x), sizeof(a))

using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef long double ldb;
typedef pair<ll, ll> pii;

const int maxn = 110;
const ll mod = 1000000007;

int n, a[maxn];
ll f[maxn][maxn][maxn], g[maxn][maxn][maxn], sf[maxn][maxn][maxn], sg[maxn][maxn][maxn];

void solve() {
	scanf("%d", &n);
	for (int i = 1; i <= n; ++i) {
		scanf("%d", &a[i]);
		a[i] = min(a[i], n);
		f[i][i][1] = g[i][i][1] = 1;
		for (int j = 1; j <= n; ++j) {
			sf[i][i][j] = sg[i][i][j] = 1;
		}
	}
	for (int p = 2; p <= n; ++p) {
		for (int i = 1, j = p; j <= n; ++i, ++j) {
			for (int x = 1; x <= a[i]; ++x) {
				g[i][j][x] = f[i][j][x] = g[i + 1][j][x - 1];
			}
			for (int k = i; k < j; ++k) {
				for (int x = 1; x <= a[k + 1]; ++x) {
					g[i][j][x] = (g[i][j][x] + sg[i][k][x] * f[k + 1][j][x] % mod + g[i][k][x] * sf[k + 1][j][x - 1] % mod) % mod;
				}
			}
			for (int x = 1; x <= n; ++x) {
				sf[i][j][x] = (sf[i][j][x - 1] + f[i][j][x]) % mod;
				sg[i][j][x] = (sg[i][j][x - 1] + g[i][j][x]) % mod;
			}
		}
	}
	printf("%lld\n", sg[1][n][n]);
}

int main() {
	int T = 1;
	// scanf("%d", &T);
	while (T--) {
		solve();
	}
	return 0;
}

标签:AtCoder,limits,Contest,sum,Sequence,一棵树,long,maxn
From: https://www.cnblogs.com/zltzlt-blog/p/17322585.html

相关文章

  • AtCoder Beginner Contest 223(D,E,F)
    AtCoderBeginnerContest223(D,E,F)D(拓扑排序)D大意就是有\(n\)个点,\(m\)个关系,其中关系是指\(u\)和\(v\),在排序里面使得\(u\)的位置再\(v\)的位置的前面要求找到一个排序满足上述条件的序列中字典序最小的那一个这个使用拓扑排序,并加上优先队列即可只要找到\(n\)个数,即为......
  • AtCoder Beginner Contest 293 补题记录 (E-G)
    E题意:给定A,X,M,计算(A0+A1+A2+...+AX-1)modM(1<=A,M<=109,1<=X<=1012)。 根据等比数列求和公式,(A0+A1+A2+...+AX-1)modM=((AX-1)/(A-1))modM。然而,此题如果用求和公式来求解显然是行不通的,下面会给出原因。 如果我们要用求......
  • 2022 Shanghai Collegiate Programming Contest B
    知识点:差分约束Link:https://codeforces.com/gym/103931/problem/B。被卡SPFA了呃呃。一看出题人是这个人:如何看待SPFA算法已死这种说法?-fstqwq的回答-知乎,那没事了。简述给定参数\(n,q\),表示有一个长度为\(n\)的合法括号序列,且有\(q\)组限制。每组限制均为......
  • AtCoder Regular Contest 104 D Multiset Mean
    洛谷传送门AtCoder传送门很平凡的一道计数啊。考虑将所有数都减去\(x\),那么就要求选的数和为\(0\)。正负分开考虑,\(0\)可以任意选。需要多重背包求\(f_{i,j}\)表示选\(1\simi\)的数和为\(j\)的方案数。前缀和优化是平凡的。code//Problem:D-MultisetMean......
  • Bracket Sequence
    #include<iostream>usingnamespacestd;#defineintlonglongconstintp=1e9+7;intquick(inta,intb,intp){intres=1;while(b){if(b&1)res=res*a%p;a=a*a%p;b>>=1;}returnres;}intc(inta,int......
  • 2012-2013 ACM-ICPC, NEERC, Moscow Subregional Contest题解
    题目链接:2012-2013ACM-ICPC,NEERC,MoscowSubregionalContestC.Cinderella(贪心)思路答案为大于平均值的数的数量代码#include<bits/stdc++.h>usingnamespacestd;usingi64=longlong;intmain(){ios::sync_with_stdio(false);cin.tie(nullptr);......
  • codeforces#FF DIV2C题DZY Loves Sequences(DP)
    题目地址:http://codeforces.com/contest/447/problem/CC.DZYLovesSequencestimelimitpertestmemorylimitpertestinputoutputa,consistingof nai, ai + 1, .........
  • 1811E Living Sequence 两种解法
    思维进制转换数位DP无前导0T3Problem-1811E-Codeforces题目大意从一个不含有数字4的递增序列中找第k个数并输出。如\(1,2,3,5,6,7,8,9,10,11,12\),\(k=4\)时输出\(5\)。思路1有一个巧妙的解法:考虑这个问题,从一个没有限制的从1开始的递增序列找出第k个数,......
  • HDU 5045 Contest(费用流)
    题目地址:HDU5045终于在比赛中用网络流A了一道题。。。刷了那么多网络流,终于用到一次了。。虽然题目很简单,但是还是要纪念一下下。。。我这题的思路就是求m/n次费用流,每n个算作同一轮,对这同一轮的求最大费用流。建图就很简单了,最简单的二分图模型。代码如下:#include<iostre......
  • C. Sequence Master
    题目链接挺有意思的一道题题意:给定一个\(2*n\)长度的数组\(p\),要求构造一个长度也为\(2*n\)的整数数组\(q\),使得\(q\)满足从\(q\)中任选\(n\)个数字的积等于\(q\)中剩下\(n\)个数的和,求出\(p\)与\(q\)的最短距离最短距离定义为对应元素差的绝对值之和由于\(q\)的要求有点严苛......