codeforces 1284C New Year and Permutation

Nefeertari發表於2020-11-13

Recall that the permutation is an array consisting of n distinct integers from 1 to n in arbitrary order. For example, [2,3,1,5,4] is a permutation, but [1,2,2] is not a permutation (2 appears twice in the array) and [1,3,4] is also not a permutation (n=3 but there is 4 in the array).

A sequence a is a subsegment of a sequence b if a can be obtained from b by deletion of several (possibly, zero or all) elements from the beginning and several (possibly, zero or all) elements from the end. We will denote the subsegments as [l,r], where l,r are two integers with 1≤l≤r≤n. This indicates the subsegment where l−1 elements from the beginning and n−r elements from the end are deleted from the sequence.

For a permutation p1,p2,…,pn, we define a framed segment as a subsegment [l,r] where max{pl,pl+1,…,pr}−min{pl,pl+1,…,pr}=r−l. For example, for the permutation (6,7,1,8,5,3,2,4) some of its framed segments are: [1,2],[5,8],[6,7],[3,3],[8,8]. In particular, a subsegment [i,i] is always a framed segments for any i between 1 and n, inclusive.

We define the happiness of a permutation p as the number of pairs (l,r) such that 1≤l≤r≤n, and [l,r] is a framed segment. For example, the permutation [3,1,2] has happiness 5: all segments except [1,2] are framed segments.

Given integers n and m, Jongwon wants to compute the sum of happiness for all permutations of length n, modulo the prime number m. Note that there exist n! (factorial of n) different permutations of length n.

題目大意:
給你n個數隨意排列,問每種排法區間左右之差和區間內極值之差相等情況之和。
摘抄了大佬的思路:https://blog.csdn.net/qq_43326267/article/details/103843503

這個題很有意思呀。就是給你一個n,求n的所有排列裡區間左右端點的差等於區間內極差的區間的和。

其實手枚一下就可以發現,其實滿足這個條件的區間內的數一定是連續的。

所以我們從區間長度入手,對於每個長度的區間看對應了多少個排列滿足要求。

這就很簡單了呀。我們列舉區間的極差i,考慮選差值為i的i+1個數有n-i種選法,區間內的順序隨意,整體看這i+1個數為一組,另外的n-i-1個數為n-i-1個組,這n-i個組的順序同樣隨意。

所以就有:

在這裡插入圖片描述

然後這個題就沒了。

#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int inf=1e6+7;
const int N=250000 ;
ll inv[N];
int main(){
	int n,m;	
	cin>>n>>m;
	inv[0]=1;
	for(int i=1;i<=n;i++)
	inv[i]=inv[i-1]*i%m;
	ll ans=0;
	for(int i=0;i<=n-1;i++)
	ans=(ans+(n-i)*inv[i+1]%m*inv[n-i]%m)%m;
	cout<<ans;
	
	
}

相關文章