@noi.ac - [email protected] shuffle

目录

  • @[email protected]
  • @[email protected]
  • @accepted [email protected]
  • @[email protected]

@[email protected]

给定一个长度为 n 的序列 s1,s2,…,sn,它有 2^n?1 个非空子序列。请对于每个 k=0,1,2,…,n 统计 s 有多少非空子序列 a 经过重排成 b 后,ai = bi 的位置数量的最小可能值恰好为k。

input
第一行包含一个正整数 n ,表示序列的长度。
第二行包含 n 个正整数 s1,s2,…,sn,表示序列s。

output
输出 n+1 行,每行输出一个整数,第 i 行输出 k = i+1 的非空子序列数量。因为答案可能很大,请对 1000000007(=10^9+7) 取模输出。

sample input
5
2 3 2 5 5
sample output
18
11
2
0
0
0

对于 100% 的数据,1≤si≤n,n≤250000。

@[email protected]

不难观察发现,序列重排后与原位置相同的位置数最小可能值只与这个序列的众数有关。

(1)当 2*众数的出现次数 ≤ 序列长度 时,最小可能值为 0。
易证。具体操作方法是每次选择某个众数和其他的数交换。可以归纳验证该方法的可行性。

(2)否则,最小可能值 = 2*众数的出现次数 - 序列长度。
保留这些位置的数不动,然后就可以归纳到上面那一种情况。

枚举众数是哪个数。
因为情况(1)不好考虑,所以我们只考虑情况(2),用总数(2^n - 1)减去情况(2)的方案数就可以得到情况(1)的方案数。

考虑枚举出来的众数为 a,它的出现次数为 t,我们所选取的子序列长度为 l,其中包含 a 的个数为 x。
则:
\[ans[2*x - l] = \sum(C_{t}^{x}*C_{n-t}^{l-x})\]
因为所有数的出现次数总和为 n,均摊下来是一个 O(n^2) 的算法。

标算使用的是卷积优化,但是模数实在有些恶心,所以我们机房的大佬想出来另一种算法爆踩标算:

先换元:令 d = 2*x - l,消去 l。可以得到:
\[ans[d] = \sum(C_{t}^{x}*C_{n-t}^{x-d})\]

由组合数的简单性质,可得:
\[ans[d] = \sum(C_{t}^{t-x}*C_{n-t}^{x-d})\]

考虑其组合意义,可以发现它等于:
\[ans[d] = \sum(C_{n}^{t-d})\]

然后均摊 O(n),代码复杂度、时间复杂度、思维复杂度三重爆踩标算。

@accepted [email protected]

#include<cstdio>
const int MOD = int(1E9) + 7;
const int MAXN = 250000 + 5;
inline int add(int x, int y) {return (x + y) % MOD;}
inline int sub(int x, int y) {return add(x, MOD-y);}
inline int mul(int x, int y) {return 1LL*x*y % MOD;}
int pow_mod(int b, int p) {
    int res = 1;
    while( p ) {
        if( p & 1 ) res = mul(res, b);
        b = mul(b, b);
        p >>= 1;
    }
    return res;
}
int a[MAXN], cnt[MAXN], ans[MAXN], n;
int fct[MAXN], inv[MAXN];
void init() {
    fct[0] = 1;
    for(int i=1;i<=n;i++)
        fct[i] = mul(fct[i-1], i);
    inv[n] = pow_mod(fct[n], MOD - 2);
    for(int i=n-1;i>=0;i--)
        inv[i] = mul(inv[i+1], i + 1);
}
inline int comb(int n, int m) {
    if( n < m ) return 0;
    else return mul(fct[n], mul(inv[m], inv[n-m]));
}
int main() {
    scanf("%d", &n); init();
    for(int i=1;i<=n;i++) {
        int x; scanf("%d", &x);
        a[x]++;
    }
    for(int i=1;i<=n;i++)
        cnt[a[i]]++;
    ans[0] = sub(pow_mod(2, n), 1);
    for(int t=1;t<=n;t++)
        if( cnt[t] )
            for(int d=1;d<=t;d++)
                ans[d] = add(ans[d], mul(cnt[t], comb(n, t-d)));
    for(int i=1;i<=n;i++)
        ans[0] = sub(ans[0], ans[i]);
    for(int i=0;i<=n;i++)
        printf("%d\n", ans[i]);
}

@[email protected]

康复计划 - 2。

如果没有 zxb 与 typ 大佬的开导我可能真的要去写 拆系数fft/三模数ntt。

大佬您们太强了 orz。

顺便好像 typ 大佬是用的打表找到的规律,太强了我肯定看半天都看不出来规律 orz。

果然组合数学就是瞎搞公式2333

原文地址:https://www.cnblogs.com/Tiw-Air-OAO/p/11073857.html

时间: 2024-10-09 14:54:05

@noi.ac - [email protected] shuffle的相关文章

@noi.ac - [email&#160;protected] cleaner

目录 @[email protected] @[email protected] @accepted [email protected] @[email protected] @[email protected] 小Q计划在自己的新家中购置一台圆形的扫地机器人.小Q的家中有一个宽度为 m 的走廊,走廊很长,如果将这个走廊的俯视图画在平面直角坐标系上的话,那么走廊的两堵墙可以分别看作直线 y=0 和直线 y=m,两堵墙之间的部分代表走廊. 小Q会按照顺序依次在走廊中安置 n 个家具.第 i 个家具

@noi.ac - [email&#160;protected] game

目录 @[email protected] @[email protected] @accepted [email protected] @[email protected] @[email protected] 小 Q 和小 T 正在玩一种双人游戏.m 张木牌从左往右排成一排,第 i 张木牌上写着一个正整数 bi.小 Q 和小 T 轮流行动总计 m 轮,小 Q 先手.在每一轮中,行动方需要选择最左或者最右的一张木牌并将其拿走.游戏最后每个人的得分即为他拿走的木牌上写着的数字之和,得分较大的一方

@noi.ac - [email&#160;protected] 老头子的话

目录 @[email protected] @[email protected] @accepted [email protected] @[email protected] @[email protected] 老头子是小学校长,小学生(大哥)们都很听老头子的话.一天,老头子给小学生(大哥)们发苹果吃. 一共有 n 个小学生(大哥),老头子每一次会等概率选择一位小学生(大哥)并给他一个苹果.一个小学生(大哥)变得开心当且仅当他拥有的苹果数 ≥k. 因为老头子年纪大了,所以他想要你告诉他,期望多

git clone gi[email&#160;protected]:xxx.git Permission denied (publickey) 问题解决办法

本文主要解决一个问题 git clone 出现公共密钥的权限问题.症状如下: CasondeMacBook-Pro:devops cason$ git clone [email protected]:360yyou/yyou.gitCloning into 'yyou'...Permission denied (publickey).fatal: Could not read from remote repository. Please make sure you have the correc

Xcode连接[email&#160;protected] (oschina git代码托管)

Xcode 已经集成了git,建立新项目时钩选使用git,然后按照下面步骤让Xcode和git@osc 建立连接. 第一步:成生SSH密钥 打开终端命令工具,输入命令:ssh-keygen -t rsa -C "[email protected]" 注意ssh-keygen没有空格.屏幕输出: Generating public/private rsa key pair. Enter file in which to save the key (/Users/diaosi/.ssh/i

使用Mac OS X 终端连接[email&#160;protected]

环境准备: Xcode(直接AppStore下载安装) Git(可以在http://code.google.com/p/git-osx-installer/下载git安装程序,或者在https://www.kernel.org/pub/software/scm/git/下载源码安装.) 源码安装过程: 解压源码包 tar xjvf git-1.8.3.tar.bz2 编译 cd git-1.8.3 ./configure --prefix=/usr/local make 安装 sudo make

GDCPC2016题解 by [email&#160;protected] | Asiimov

Problem A. ABCD 题目大意 给出一个四边形四条边AB.CD.AD.BC及两条对角线AC.BD的长度,问这个四边形的顶点能否在一个圆上 算法思路 通过余弦定理考察∠ACB与∠ADB是否相等即可. 时间复杂度: O(1) 代码 /** * Copyright ? 2016 Authors. All rights reserved. * * FileName: A.cpp * Author: Beiyu Li <[email protected]> * Date: 2016-05-09

@codeforces - [email&#160;protected] Oleg and chess

目录 @description - [email protected] @[email protected] @part - [email protected] @part - [email protected] @part - [email protected] @part - [email protected] @accepted [email protected] @[email protected] @description - [email protected] 给定一个 n*n 的棋

@hdu - [email&#160;protected] Counting Stars

目录 @[email protected] @[email protected] @accepted [email protected] @[email protected] @[email protected] 给定一个 n 点 m 边的无向图(无重边自环),求有多少子图形如,包含 4 个点 {A, B, C, D} 与 6 条边 {AB, BC, CD, DA, AC}. 原题链接. @[email protected] 一个并不常用的黑科技:三元环计数. mark一下博客地址. 注意到题目