首页 > 其他分享 >CF1542E2 题解

CF1542E2 题解

时间:2023-05-11 23:45:21浏览次数:31  
标签:limits int 题解 sum times SI SSI CF1542E2

首先,考虑枚举其中一个的逆序对数,这里绕不开的问题就是求 \(I_{i,j}\) 表示 \(1-i\) 的排列中逆序对个数为 \(j\) 的排列数,不妨把这里逆序对变成顺序对(为了方便描述,显然是等价的)。

有个很显然的trick:把所有数按 \(1-n\) 顺序插入。然后当插入第 \(i\) 个数时,枚举它前面有 \(k\) 个数,则顺序对会增加 \(k\) 个。于是 \(I_{i,j}\leftarrow\sum\limits_{k=0}^{i-1} I_{i-1,j-k}\)。

复杂度: \(n\times n^2\times n\),是 \(O(n^4)\) 的。

前缀和优化一下,记 \(SI_{i,j}=\sum\limits_{k=0}^j I_{i,j}\),那么 \(I_{i,j}\leftarrow SI_{i-1,j}-SI_{i-1,j-i+1}\),就可以 \(O(n^3)\) 了。

最初:\(O(n^7)\)

考虑这题,用递推(我也不知道是怎么想到的)。

记 \(f_i\) 表示本题长度为 \(i\) 时的答案。

考虑枚举两个排列的最后一位,分别为 \(p,q\)。

若 \(p=q\),则 \(f_i\leftarrow i\times f_{i-1}\)。

否则,枚举 \(p,q\) 和直接第一、二个排列之前的逆序对数 \(j,k\)。

则 \(f_i\leftarrow \sum\limits_{p=1}^i\sum\limits_{q=p+1}^i\sum\limits_{j=p-1}^{p-1+(i-2)\times(i-2)/2}\sum\limits_{k=q-1}^{j-1} I_{i-1,j-(p-1)}\times I_{i-1,k-(q-1)}\)。

两个加起来即可,复杂度是 \(O(n^7)\) 的,非常优秀,能过样例,显然会超时。

优化:\(O(n^5)\)

\(\sum\limits_{p=1}^i\sum\limits_{q=p+1}^i\sum\limits_{j=p-1}^{p-1+(i-2)\times(i-2)/2}\sum\limits_{k=q-1}^{j-1} I_{i-1,j-(p-1)}\times I_{i-1,k-(q-1)}=\sum\limits_{p=1}^i\sum\limits_{q=p+1}^i\sum\limits_{j=p-1}^{p-1+(i-2)\times(i-2)/2} I_{i-1,j-(p-1)}\sum\limits_{k=q-1}^{j-1} I_{i-1,k-(q-1)}\)

\(=\sum\limits_{p=1}^i\sum\limits_{q=p+1}^i\sum\limits_{j=p-1}^{p-1+(i-2)\times(i-2)/2} I_{i-1,j-(p-1)}SI_{i-1,j-q}\)

有个细节,就是 \(j-q\) 要 \(\ge0\),所以 \(j\) 要从 \(q\) 开始枚举 \((q\ge p-1)\)。

于是变成 \(\sum\limits_{p=1}^i\sum\limits_{q=p+1}^i\sum\limits_{j=q}^{p-1+(i-2)\times(i-2)/2} I_{i-1,j-(p-1)}SI_{i-1,j-q}\)

搞掉了一个 \(n^2\) ,于是变成了 \(O(n^5)\)。

类似优化:\(O(n^4)\)

\(\sum\limits_{p=1}^i\sum\limits_{q=p+1}^i\sum\limits_{j=q}^{p-1+(i-2)\times(i-2)/2} I_{i-1,j-(p-1)}SI_{i-1,j-q}\) 之前推到了这个式子。

下面优化 \(q\)。考虑 \(\sum\limits_{q=p+1}^i\sum\limits_{j=q}^{p-1+(i-2)\times(i-2)/2}\),这等价于 \(\sum\limits_{j=p+1}^{p-1+(i-2)\times(i-2)/2}\sum\limits_{q=p+1}^{\min(j,i)}\)。

于是 \(\sum\limits_{p=1}^i\sum\limits_{q=p+1}^i\sum\limits_{j=q}^{p-1+(i-2)\times(i-2)/2} I_{i-1,j-(p-1)}SI_{i-1,j-q}=\sum\limits_{p=1}^i\sum\limits_{j=p+1}^{p-1+(i-2)\times(i-2)/2} I_{i-1,j-(p-1)}\sum\limits_{q=p+1}^{\min(j,i)}SI_{i-1,j-q}\)。

记 \(SSI\) 为 \(SI\) 的前缀和,则这个式子变成 \(\sum\limits_{p=1}^i\sum\limits_{j=p+1}^{p-1+(i-2)\times(i-2)/2} I_{i-1,j-(p-1)}\times T\)。

其中 \(T=\begin{cases}SSI_{j-p-1}(j\le i)\\SSI_{j-p-1}-SSI_{j-i-1}(j>i)\end{cases}\)(那篇题解这里就错了)。

终极优化:\(O(n^3)\)

都优化到这个份上了,相信大家能想到这个变成三次方的优化。

类似的 \(\sum\limits_{p=1}^i\sum\limits_{j=p+1}^{p-1+(i-2)\times(i-2)/2}I_{i-1,j-(p-1)}\times T=\sum\limits_{j=2}^{p-1+(i-2)\times(i-2)/2}\sum\limits_{p=1}^{\min(i,j-1)}I_{i-1,j-(p-1)}\times T\)。

显然是把 \(I_{i-1,j-(p-1)}\times T\) 这整个去前缀和。

记 \(S\) 为 \(I_{k+2}\times SSI_k\) 的前缀和,这个式子就变成了:\(\sum\limits_{j=2}^{i\times(i-1)/2} T\)。

其中 \(T=\begin{cases}S_{j-2}(j\le i)\\S_{j-2}-S_{j-i-1}-SSI_{j-i-1}\times(SI_{j}-SI_{j+i-1}) \end{cases}\) 。

这样就是 \(O(n^3)\) 啦!


注意到三次方空间会爆,于是把枚举 \(i\) 的那一维想办法优化一下就行了。

代码:

#include<bits/stdc++.h>
#define LL long long
#define fr(x) freopen(#x".in","r",stdin);freopen(#x".out","w",stdout);
using namespace std;
const int N=505;
int n,mod,I[N*N>>1],SI[N*N>>1],SSI[N*N>>1],S[N*N>>1],f[N];
inline int AD(int x,int y){x+=y;return x>=mod?x-mod:x;}
inline void ad(int &x,int y){x+=y;(x>=mod)&&(x-=mod);}
int main()
{
	scanf("%d%d",&n,&mod);I[0]=SI[0]=SSI[0]=1;f[0]=0;
	for(int i=1;i<=n;i++)
	{
		f[i]=1ll*f[i-1]*i%mod;
		for(int j=2;j<=i*(i-1)/2;j++)
		{
			if(j<=i) ad(f[i],S[j-2]);
			else ad(f[i],AD(S[j-2],mod-AD(S[j-i-1],1ll*SSI[j-i-1]*AD(SI[j],mod-SI[j-i+1])%mod)));
		}
		for(int j=0;j<=i*(i-1)/2;j++)
		{
			if(j>=i) I[j]=AD(SI[j],mod-SI[j-i]);
			else I[j]=SI[j];
		}
		SI[0]=SSI[0]=I[0];S[0]=1ll*I[2]*SSI[0]%mod;
		for(int j=1;j<=i*(i+1)/2;j++) SI[j]=AD(SI[j-1],I[j]),SSI[j]=AD(SSI[j-1],SI[j]),S[j]=AD(S[j-1],1ll*I[j+2]*SSI[j]%mod);
	}
	printf("%d",f[n]);
	return 0;
}

个人感觉实现的比较优秀,从七次方优化到三次方的 \(dp\) 还是很精妙的。

标签:limits,int,题解,sum,times,SI,SSI,CF1542E2
From: https://www.cnblogs.com/HaHeHyt/p/17392584.html

相关文章

  • 「题解」ABC241Ex Card Deck Score
    小时候最喜欢看的一集没有\(b_i\)怎么做?答案是\([x^m]\prod\frac{1}{1-a_ix}\),我们知道它可以分解为\(\sum\frac{R_i}{1-a_ix}\),其中\(R_i\)是一个常数。具体构造就是上面EI的blog,和中国剩余定理及其类似。那么\(R_i=\frac{1-a_ix}{\prod_j(1-a_jx)}\bmod(1-a_ix)\)......
  • YACS 2022年8月月赛 甲组 T1 约瑟夫问题 题解
    又来填坑了(大雾题目链接#1.为什么用树状数组做多了题目,看一眼这题就知道要用数据结构了,进一步分析就可以知道这是一道二分和树状数组的题目。(其实用变形的链表$n\sqrt{n}$卡卡常也可以吧)#2.具体思路首先设定$n$个位置,第$i$个位置为$1$代表这个人还没出局,否则代表出......
  • agc029c 题解
    首先随便想个暴力,对于\(a_i>a_{i-1}\),我们直接往字符串的末尾加上一些最小的字符。对于\(a_i\lea_{i-1}\),我们保留前缀之后随便加一个位置的\(1\)。发现这个随便的位置不是很好找,于是想到用二分转枚举为判断。二分最大的字符(可以转化为数字)\(x\),每次我们只往最后一......
  • 51nod 1227 平均最小公倍数 题解
    题目大意\[A(n)=\frac{1}{n}\sum_{i=1}^{n}\text{lcm}(n,i)\\F(a,b)=\sum_{i=a}^{b}A(i)\\\]给定\(a,b\),求\(F(a,b)\mod10^9+7\)。\(1\lea\leb\le10^9\)。思路首先我们可以想到,如果我们定义\(B(n)=\underset{i=1}{\overset{n}{\sum}}A(i)\),那么\(F(a,......
  • 【题解】P4331 [BalticOI 2004]Sequence 数字序列
    以各种方式出现被玩烂的题目,算是小trick题?cpeditor意外地好用思路可并堆。平行时空同位体:CF13CP4331P4597CF713CP2893已知做法:\(O(n^2)\)dp:令\(f[i][j]\)为前\(i\)个数不超过\(j\)的最小代价优化:使用堆维护dp产生的折线(P4597题解区)\(O(n\logn......
  • AtCoder Beginner Contest 298 题解
    题面:https://atcoder.jp/contests/abc298/tasks_printA-JobInterview直接模拟即可。#include<bits/stdc++.h>#include<ext/pb_ds/assoc_container.hpp>#include<ext/pb_ds/tree_policy.hpp>#include<ext/pb_ds/hash_policy.hpp>usingnamespace......
  • # Codeforces Round 872 (Div. 2) 题解
    CodeforcesRound872(Div.2)题解A.LuoTianyiandthePalindromeString略B.LuoTianyiandtheTable略C.LuoTianyiandtheShow略D1.LuoTianyiandtheFloatingIslands(EasyVersion)题意在树上随机撒\(k(k\leq3)\)个关键点,规定一个点是好的当且仅当这个......
  • springboot跨域问题解决方案
    以下内容仅供自己学习使用,侵权私聊必删。在进行前后端交互的时候,往往会遇到以下的跨域问题。那么解决这种跨域的话,可以使用以下这种方法:(引自于程序员青戈)创建config配置目录新建CorsConfig类然后把下面的内容复制进去根据自己需要修改以下就可以解决跨域问题啦importo......
  • P1676 [USACO05FEB] Aggressive cows G 题解
    题目传送门解题思路最大值最小化问题,考虑二分答案。首先要排序,保证序列单调不降,然后求出两个隔间之间的距离。sort(a+1,a+1+n);for(rii=1;i<=n;i++) dis[i]=a[i+1]-a[i];二分出一个\(mid\),判断它是否合法:每次累加距离,如果距离和比\(mid\)大,说明当前可以分配牛,记录数量......
  • Codeforces Round 683 (Div. 1, by Meet IT) ABCDF题解
    F和D都在ABC上做过类似的,但是没打好,道心破碎。。。。A.Knapsack若物品质量在[(w+1)/2,w]之间做完了否则一直贪心加voidsolve(){intn;llw;cin>>n>>w;intc=n;for(inti=1;i<=n;i++){cin>>a[i];if(a[i]>w)c--;}if(!c){......