CF1542E2 Abnormal Permutation Pairs (hard version) 题解
怎么会有这么离谱的题目啊。
【模板】前缀和优化 dp。
思路#
考虑一个基本的东西。
由于要求字典序的限制。
我们可以枚举最长公共前缀计算。
考虑如何求长度为
设
就是枚举新的数放在那里。
不难看出可以前缀和优化。
就可以
到这里都是比较简单的。
考虑如何算答案。
首先列出较为朴素的
枚举最长公共前缀长度
稍微整理一下。
发现又可以前缀和优化。
设
这个时候,我发现了后面只与
这个式子已经可以
但如何把它优化成
然后就发现我们走了很没有前途的一步,我也在这里卡了很久。
那么我们不得不往回退一步。
我们考虑继续前缀和优化。
设
发现这玩意还可以前缀和优化。
设
设
然后就做完了。
可能有一些边界情况需要来判断。
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;
}
作者:JiaY19
出处:https://www.cnblogs.com/JiaY19/p/17832696.html
版权:本作品采用「署名-非商业性使用-相同方式共享 4.0 国际」许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· 写一个简单的SQL生成工具
· AI 智能体引爆开源社区「GitHub 热点速览」
· C#/.NET/.NET Core技术前沿周刊 | 第 29 期(2025年3.1-3.9)