列表

详情


NC213975. 生涯回忆录

描述

树剖姐姐想写OI生涯回忆录.

树剖姐姐有n个回忆,第i个回忆有一个正整数权值ai.

这些回忆构成了一个集合.

由于回忆太多,树剖姐姐不一定能全部写完,于是她决定选择集合的一个子集写生涯回忆录(选择的子集可能为空,这意味着树剖把回忆录咕了).

容易知道一共有2n种可能的生涯回忆录.

当然,写出的生涯回忆录往往会有遗憾,定义一个生涯回忆录的遗憾为:最小的正整数x使得 写出这个生涯回忆录的集合所包含的所有回忆中,没有权值ai使得ai=x

现在树剖想知道,她所有可能写出的生涯回忆录的遗憾之和对20000311取模的结果.


输入描述

第一行一个正整数n.

第二行n个正整数,第i个数是ai.

输出描述

一行一个数,表示答案

示例1

输入:

7
1 1 1 2 3 3 3

输出:

345

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

Python3(3.9) 解法, 执行用时: 1483ms, 内存消耗: 73076K, 提交时间: 2020-11-28 13:35:25

mod = 20000311
n = int(input())
c = [0 for i in range(n+5)]
mp = list(map(int, input().split()))
for i in mp:
    if i <= n:
        c[i] += 1
    else :
        c[n+2] += 1
ksm = [1]
for i in range(1, n+3):
    ksm.append(ksm[i-1] * 2 % mod)
fac1 = [1]
for i in range(1, n+1):
    fac1.append(fac1[i-1] * (ksm[c[i]] - 1) % mod)
fac2 = [1 for i in range(n+5)]
for i in range(n+2, 0, -1):
    fac2[i] = fac2[i+1] * ksm[c[i]] % mod
ans = 0
for i in range(1, n+2):
    ans += i * fac1[i-1] * fac2[i+1] % mod
    ans %= mod
print(ans)

C++(clang++11) 解法, 执行用时: 207ms, 内存消耗: 8940K, 提交时间: 2020-11-22 19:15:57

#include<bits/stdc++.h>
using namespace std;
const int N=5e5+5,mod=20000311;
int n;
int a[N];
map<int,int> mp;
int pw[N];
signed main(){
	scanf("%d",&n);
	for(int i=1;i<=n;i++) scanf("%d",&a[i]),mp[a[i]]++;
	pw[0]=1;
	for(int i=1;i<=n;i++) pw[i]=pw[i-1]*2ll%mod;
	int pre=1,sum=0,ans=0;
	for(int i=1;i<=n+1;i++){
		sum+=mp[i];
		ans=(ans+(1ll*pre*pw[n-sum]%mod*i%mod))%mod;
		if(mp[i]==0) break;
		pre=1ll*pre*(pw[mp[i]]-1)%mod;
	}
	cout<<ans;
	return 0;
}

上一题