2022ICPC网络赛第二场 - G. Good Permutation

组合数学 + 树形DP + 单调栈

题目详情 - G Good Permutation (pintia.cn)

题意

对于一个 [1,n](1<=n<=106) 的排列 p,有 m(1<=m<=106) 个限制

  1. 每个限制给定一组下标 l,r, 满足 max(pl,pl+1,...,pr)min(pl,pl+1,...,pr)=rl

  2. m 个区间只有不相交完全包含两种关系

求满足上述条件的排列个数

思路

  1. 区间最大 - 区间最小 == 区间长度 - 1,意味着这个长度为 len 的区间就是连续 len 个数的排列

  2. 因为区间没有相交的情况,结合第一条,容易想到可以递归子问题求解

  3. 设大区间为结点 u,它完全包含的各个小区间为结点 vi, 共有 tot 个,则 ansu=ansvi(lenulenvi+tot)!

意思是把子区间用捆绑法当作是一个点,则一共有 lenulenvi+tot 个点,它们可以任意排列,再乘子区间内部的答案即可

  1. 现在考虑如何建树,可将区间按左端点递增,右端点递减排序并去重,用单调栈维护当前大区间的右端点(从栈底到栈顶变小),枚举第 i 个区间时
    1. 如果其左端点 > 大区间右端点,则当前大区间无法包括第 i 个区间,要 pop 出来,直到当前栈顶的大区间能够包含区间 i
    2. 把当前区间压栈

注意结构体用 unique 函数要重载 ==

代码

#include <bits/stdc++.h>
using namespace std;
#define endl "\n"

typedef long long ll;
typedef pair<int, int> PII;

const int N = 1e6 + 10;
const int mod = 1e9 + 7;
int n, m;

struct Seg
{
	int l, r;
	bool operator<(const Seg &x) const
	{
		if (l == x.l)
			return r > x.r;
		return l < x.l;
	}
	bool operator==(const Seg &x) const
	{
		return l == x.l && r == x.r;
	}
};
vector<Seg> c;
stack<int> stk;
vector<vector<int> > G(N);
ll fac[N];
void add(int u, int v)
{
	G[u].push_back(v);
}

ll dfs(int u)
{
	ll ans = 1;
	int sum = c[u].r - c[u].l + 1;
	for (int v : G[u])
	{
		sum -= c[v].r - c[v].l + 1;
		ans = ans * dfs(v) % mod;
	}
	return ans * fac[sum + G[u].size()] % mod;
}

void presolve(int n)
{
	fac[0] = 1;
	for (int i = 1; i <= n; i++)
		fac[i] = fac[i-1] * i % mod;
}
int main()
{
	scanf("%d%d", &n, &m);
	presolve(n);
	c.push_back({1, n});
	for (int i = 1; i <= m; i++)
	{
		int l, r;
		scanf("%d%d", &l, &r);
		c.push_back({l, r});
	}
	sort(c.begin(), c.end());
	c.erase(unique(c.begin(), c.end()), c.end());
	m = c.size();
	stk.push(0);
	for (int i = 1; i < m; i++)
	{
		while(!stk.empty() && c[i].l > c[stk.top()].r)
			stk.pop();
		add(stk.top(), i);
		stk.push(i);
	}
	cout << dfs(0) << endl;
    return 0;
}
posted @   hzy0227  阅读(134)  评论(4编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
点击右上角即可分享
微信分享提示