题解 计数

传送门

  • 多测题一定要检查一遍solve函数里有没有写 exit(0)

没有限制的情况很简单,DP或记搜都行,考虑枚举左子树大小
有限制的情况:
有一步转化:
\(A_i\)\(i\) 在中序遍历里的排名
\(u<v\) 时,若让 \(A_u < A_v\),发现 \(v\) 一定在 \(u\) 的右子树里
这就\(u\) 的左子树大小产生了限制
若左子树过大,\(u\) 会落到左子树
\(u>v\) 同理
于是记录 \(l[i], r[i]\)\(i\) 的可行左子树大小范围
于是可以正常DP

  • 在树的遍历顺序下,两个点的id差,位置和它们的子树大小有时可以相互限制
Code:
#include <bits/stdc++.h>
using namespace std;
#define INF 0x3f3f3f3f
#define N 450
#define ll long long
#define reg register int
//#define int long long 

char buf[1<<21], *p1=buf, *p2=buf;
#define getchar() (p1==p2&&(p2=(p1=buf)+fread(buf, 1, 1<<21, stdin)), p1==p2?EOF:*p1++)
inline int read() {
	int ans=0, f=1; char c=getchar();
	while (!isdigit(c)) {if (c=='-') f=-f; c=getchar();}
	while (isdigit(c)) {ans=(ans<<3)+(ans<<1)+(c^48); c=getchar();}
	return ans*f;
}

int n, m;
const ll mod=1e9+7;

namespace task1{
	ll rem[N];
	ll dfs(int siz) {
		--siz;
		if (siz<=0) return 1ll;
		if (~rem[siz]) return rem[siz];
		ll ans=0;
		for (int i=0; i<=siz; ++i) 
			ans=(ans+dfs(i)*dfs(siz-i)%mod)%mod;
		return rem[siz]=ans;
	}
	void solve() {
		printf("%lld\n", dfs(n));
	}
}

namespace task{
	ll rem[N][N];
	int l[N], r[N];
	ll dfs(int u, int siz) {
		if (u>n) return siz==0ll;
		if (siz==0) return 1ll;
		if (siz<=l[u]) return 0ll;
		--siz;
		if (siz<=0) return 1ll;
		if (~rem[u][siz]) return rem[u][siz];
		ll ans=0;
		for (int i=l[u]; i<=min(r[u], siz); ++i)
			ans=(ans+dfs(u+1, i)*dfs(u+i+1, siz-i)%mod)%mod;
		//printf("dp[%d][%d]=%lld\n", u, siz, ans);
		return rem[u][siz]=ans;
	}
	void solve() {
		memset(rem, -1, sizeof(rem));
		for (int i=1; i<=n; ++i) l[i]=0, r[i]=n-i;
		for (int i=1,u,v; i<=m; ++i) {
			u=read(); v=read();
			if (u<v) r[u]=min(r[u], v-u-1);
			else l[v]=max(l[v], u-v);
		}
		//for (int i=1; i<=n; ++i) cout<<l[i]<<' '<<r[i]<<endl;
		printf("%lld\n", dfs(1, n));
	}
}

signed main()
{
	freopen("count.in", "r", stdin);
	freopen("count.out", "w", stdout);
	
	int T;
	T=read();
	while (T--) {
		n=read(); m=read();
		task::solve();
	}
	
	return 0;
}
posted @ 2021-09-14 21:38  Administrator-09  阅读(4)  评论(0编辑  收藏  举报