首页 > 其他分享 >CF1542E2 Abnormal Permutation Pairs (hard version) 题解

CF1542E2 Abnormal Permutation Pairs (hard version) 题解

时间:2023-11-14 22:00:13浏览次数:30  
标签:Pairs return int 题解 sum hard fro binom dp

怎么会有这么离谱的题目啊。

【模板】前缀和优化 dp。

思路

考虑一个基本的东西。

由于要求字典序的限制。

我们可以枚举最长公共前缀计算。

考虑如何求长度为 \(i\) 的排列有 \(j\) 个逆序对的数量。

设 \(dp_{i,j}\)。

\[dp_{i,j}=\sum_{k=0}^{i-1}dp_{i-1,j-k} \]

就是枚举新的数放在那里。

不难看出可以前缀和优化。

\[dp_{i,j}=g_{i-1,j-k}-g_{i-1,j-i} \]

就可以 \(O(n^3)\) 计算。

到这里都是比较简单的。

考虑如何算答案。

首先列出较为朴素的 \(\text{dp}\)。

枚举最长公共前缀长度 \(i\),第 \(i+1\) 位两个排列分别放 \(x,y\),后面 \(n-i-1\) 位分别会有 \(s,t\) 个逆序对。

\[\sum_{i=0}^{n-1}\binom{n}{i}i!\sum_{x=1}^n\sum_{y=x+1}^{n-i}\sum_{s=0}^{\binom{n-i+1}{2}}\sum_{t=0}^{\binom{n-i+1}{2}}[s+x-1>t+y-1] dp_{n-i-1,s}\times dp_{n-i-1,t} \]

稍微整理一下。

\[\sum_{i=0}^{n-1}\binom{n}{i}i!\sum_{x=1}^n\sum_{y=x+1}^{n-i}\sum_{s=0}^{\binom{n-i+1}{2}}\sum_{t=0}^{s+x-y-1}dp_{n-i-1,s}\times dp_{n-i-1,t} \]

\[\sum_{i=0}^{n-1}\binom{n}{i}i!\sum_{x=1}^n\sum_{y=x+1}^{n-i}\sum_{s=0}^{\binom{n-i+1}{2}}dp_{n-i-1,s}\sum_{t=0}^{s+x-y-1}dp_{n-i-1,t} \]

发现又可以前缀和优化。

设 \(g_{i,j}=\sum_{k=0}^j dp_{i,j}\)。

\[\sum_{i=0}^{n-1}\binom{n}{i}i!\sum_{x=1}^n\sum_{y=x+1}^{n-i}\sum_{s=0}^{\binom{n-i+1}{2}}dp_{n-i-1,s}\times g_{n-i-1,s+x-y-1} \]

\[\sum_{i=0}^{n-1}\binom{n}{i}i!\sum_{s=0}^{\binom{n-i+1}{2}}dp_{n-i-1,s}\sum_{x=1}^n\sum_{y=x+1}^{n-i}g_{n-i-1,s+x-y-1} \]

这个时候,我发现了后面只与 \(x-y\) 有关,那么可以枚举 \(x-y=j\)。

\[\sum_{i=0}^{n-1}\binom{n}{i}i!\sum_{s=0}^{\binom{n-i+1}{2}}dp_{n-i-1,s}\sum_{j=1}^{n-i-1}(n-i-j)\times g_{n-i-1,s+x-y-1} \]

这个式子已经可以 \(O(n^4)\) 算了,可以通关简单版本。

但如何把它优化成 \(O(n^3)\),我确实没有想到,如果有大佬会,可以教教我。

然后就发现我们走了很没有前途的一步,我也在这里卡了很久。

那么我们不得不往回退一步。

\[\sum_{i=0}^{n-1}\binom{n}{i}i!\sum_{s=0}^{\binom{n-i+1}{2}}dp_{n-i-1,s}\sum_{x=1}^{n-i}\sum_{y=x+1}^{n-i}g_{n-i-1,s+x-y-1} \]

我们考虑继续前缀和优化。

设 \(h_{i,j}=\sum_{k=0}^jg_{i,k}\)。

\[\sum_{i=0}^{n-1}\binom{n}{i}i!\sum_{s=0}^{\binom{n-i+1}{2}}dp_{n-i-1,s}\sum_{x=1}^{n-i}h_{n-i-1,s-2}-h_{n-i-1,s+x-n+i-1} \]

发现这玩意还可以前缀和优化。

\[\sum_{i=0}^{n-1}\binom{n}{i}i!\sum_{s=0}^{\binom{n-i+1}{2}}dp_{n-i-1,s}((n-i)\times h_{n-i-1,s-2}-\sum_{x=1}^{n-i}h_{n-i-1,s+x-n+i-1}) \]

设 \(f_{i,j}=\sum_{k=0}^jh_{i,k}\)。

设 \(l=s+i-n-1,r=s-2\)。

\[\sum_{i=0}^{n-1}\binom{n}{i}i!\sum_{s=0}^{\binom{n-i+1}{2}}dp_{n-i-1,s}((n-i)\times h_{n-i-1,s-2}-(f_{n-i-1,r}-f_{n-i-1,l-1})) \]

然后就做完了。

可能有一些边界情况需要来判断。

Code

/**
 * @file 1542E1.cpp
 * @author mfeitveer
 * @date 2023-11-14
 * 
 * @copyright Copyright (c) 2023
 * 
 */
#include <bits/stdc++.h>
using namespace std;

#define x first
#define y second
#define mp(x, y) make_pair(x, y)
#define fro(i, x, y) for(int i = (x);i <= (y);i++)
#define pre(i, x, y) for(int i = (x);i >= (y);i--)
#define dbg cerr << "Line " << __LINE__ << ": "
#define EVAL(x) #x " = " << (x)

typedef int64_t i64;
typedef uint32_t u32;
typedef uint64_t u64;
typedef __int128_t i128;
typedef __uint128_t u128;
typedef pair<int, int> PII;

bool ed;

const int N = 510;
const int M = 124760;

int n, m, mod, c[N][N], vis[N][N], g[M], h[M], f[M], dp[N][M];

inline int add(int x, int y)
	{ return x + y + (x + y >= mod ? -mod : 0); }
inline void init(int now)
{
	fro(j, 0, 124750) g[j] = dp[now][j];
	fro(j, 1, 124750) g[j] = add(g[j], g[j - 1]);
	fro(j, 0, 124750) h[j] = g[j];
	fro(j, 1, 124750) h[j] = add(h[j], h[j - 1]);
	fro(j, 0, 124750) f[j] = h[j];
	fro(j, 1, 124750) f[j] = add(f[j], f[j - 1]);
}
inline int C(int x, int y)
{
	if(x < y) return 0;
	if(y == 0 || x == y) return 1;
	if(vis[x][y]) return c[x][y]; vis[x][y] = 1;
	return c[x][y] = (C(x - 1, y - 1) + C(x - 1, y)) % mod;
}
inline int ask(int l, int r)
{
	if(l - 1 < 0) return g[r];
	return (g[r] - g[l - 1] + mod) % mod;
}
inline void init()
{
	dp[0][0] = 1;
	fro(i, 1, 500)
	{
		init(i - 1);
		fro(j, 0, 124750) dp[i][j] = ask(j - i + 1, j);
	}
}
inline void solve()
{
	i64 ans = 0, num = 1;
	fro(i, 0, n - 1)
	{
		i64 res = 0; init(n - i - 1);
			fro(s, 2, (n - i - 1) * (n - i - 2) / 2)
			{
				i64 res1 = 1ll * h[s - 2] * (n - i) % mod;
				int ls = s + i - n - 1;
				i64 res2 = f[s - 2] - (ls <= 0 ? 0 : f[ls - 1]);
				res2 = (res2 % mod + mod) % mod;
				(res += (res1 - res2 + mod) * dp[n - i - 1][s]) %= mod;
		}
		(ans += res * num) %= mod, num = num * (n - i) % mod;
	}
	cout << ans << endl;
}

bool st;

signed main()
{
	ios::sync_with_stdio(0), cin.tie(0);
	double Mib = fabs((&ed-&st)/1048576.), Lim = 1024;
	assert(Mib<=Lim), cerr << " Memory: " << Mib << "\n";
	cin >> n >> mod;
	init(), solve();
	return 0;
}

标签:Pairs,return,int,题解,sum,hard,fro,binom,dp
From: https://www.cnblogs.com/mfeitveer/p/17832696.html

相关文章

  • [题解] CF1051F The Shortest Statement
    TheShortestStatement给一张\(n\)个点\(m\)条边的无向连通图,保证\(m-n\le20\),\(q\)次询问求两个点间的最短路。\(n,m,q\le10^5\)。由于边数只比点数多20,所以如果我们建出这张图的一棵生成树,那么非树边至多有21条。那么现在两点之间的最短路就转化成了不......
  • 「NOIP2014」解方程 题解
    思路首先我们可以观察到\(n\)和\(m\)与\(a_i\)相比小的很多,所以我们可以考虑直接暴力求解但是\(a_i\)太大了,所以如果需要直接计算的话需要全程使用高精度算法。因为高精度算法代码量有大速度又慢我们可依考虑将\(a_i\)转化为一个极大的指数取模的结果,因为只有是模数的......
  • Q7.4.1.2. 奇怪的方格涂色 题解
    原题链接首先想到暴力网络流:考虑最小割,\(S\)表示染黑色,\(T\)表示染白色。每个格子\(i\),连\((S,i,b_i)\),\((i,T,w_i)\)。怎么处理“奇怪的方格”?连\((i,i^\prime,p_i)\)和\((i^\prime,j,+\infty)\)。表示如果\(i\)归属于\(S\)(染黑色),那么就只能忍受奇怪所带来的\(p_i\)......
  • AT_abc230_f [ABC230F] Predilection 题解
    prelogue各位在比赛的时候一定要坚信自己的式子,然后去考虑自己的实现是不是挂了。本人在今天模拟赛的时候质疑自己的式子然后不看实现100->0。analysis考虑对这个给定数组进行前缀和,然后就将问题转化成为了求这个前缀和数组的子序列的个数。对于求子序列,我们很轻松可以写出......
  • Codeforces Round 809 (Div. 2) D1. Chopping Carrots (Easy Version) 题解
    题意CodeforcesRound809(Div.2)D1.ChoppingCarrots(EasyVersion)给两个整数\(n,k\),一个数组\(a\),要求构造一个同样长度的数组\(p\),使得\(\max\limits_{1\lei\len}\left(\left\lfloor\frac{a_i}{p_i}\right\rfloor\right)-\min\limits_{1\lei\l......
  • [USACO23FEB] Equal Sum Subarrays G 题解
    [USACO23FEB]EqualSumSubarraysG题解题目链接\(O(n^5)\)暴力显然,如果修改\(a_i\)的值,只会影响包含\(a_i\)的区间的区间和。于是对于每个\(a_i\),可以将所有区间分成两类,即包含\(a_i\)的区间和不包含\(a_i\)的区间。这两种区间的区间和中最小的差值即为答案。......
  • 【洛谷 P1307】[NOIP2011 普及组] 数字反转 题解(字符串)
    [NOIP2011普及组]数字反转题目描述给定一个整数,请将该数各个位上数字反转得到一个新数。新数也应满足整数的常见形式,即除非给定的原数为零,否则反转后得到的新数的最高位数字不应为零(参见样例2)。输入格式一个整数。输出格式一个整数,表示反转后的新数。样例#1样例输入#1123样......
  • AGC041D-Problem Scores 题解
    题目链接luoguatcoder分析令\(k=\left\lfloor\frac{n}{2}\right\rfloor\)对于第三个条件,只需要满足\(\sum_{i=1}^{k+1}a[i]<\sum_{i=n-k+1}^{n}a[i]\)即可有一个\(trick\):构造一个单调不降或不增的序列可以转化为每次做一次前缀加操作例如本题要求构造一个单调......
  • [题解] CF1748E Yet Another Array Counting Problem
    YetAnotherArrayCountingProblem给你一个长度为\(n\)的序列和一个数\(m\),求有多少个长度为\(n\)的序列\(b\)满足:\(\foralli\in[1,n],b_i\in[1,m]\)。对于每个区间\([l,r]\),\(b\)中最大值最靠左的位置和\(a\)相同。\(n,m\le2\times10^5,n\ti......
  • [题解] P4435 [COCI2017-2018#2] ​​Garaža
    P4435[COCI2017-2018#2]Garaža给你一个长度为\(n\)的序列\(a\),单点改,查询区间\(\gcd\)不为1的子区间个数。\(n,Q\le10^5,a_i\le10^9\)。先看单次全局查询怎么做。考虑一个分治,每次我们要计算跨过分治中心\(mid\)的答案。因为这个是单调的,所以可以双指针做......