题目链接

戳我

题意简述

你有一个n+1个数的序列,都是1~n,其中只有一个有重复,求每个长度的本质不同的子序列个数。\(mod 1e9+7\)。

sol

说起来也很简单,设相同的数出现的位置为\(l\)和\(r\)。那么除了去掉\(r\)之后\(n\)个数的贡献,还有算上\(r\)的贡献,然后就可以了。原本\(n\)个的贡献是\(\binom{n}{i}\),加上\(r\)的贡献的话要满足在\([l,r-1]\)之间至少要选一个数,然后还要选\(r\),那么考虑将原序列(去除\(r\))分成三段,\([1,l-1],[l,r-1],[r+1,n+1]\),可以枚举长度,发现是一个卷积,于是可以愉快的NTT辣,然后模数是\(1e9+7\)?

md不管蒯一个三模数NTT暴力艹过去。总复杂度 $ O(nlogn) $ 。其实好像有 $ O(n) $ 做法,但我懒得想。

#include<cstdio>
#include<cstring>
#include<algorithm>
#define gt getchar()
#define ll long long
#define maxn 400005
#define File(s) freopen(s".in","r",stdin),freopen(s".out","w",stdout)
#define Set(a) memset(a,0,sizeof a)
using std::swap;
using std::reverse;
inline int in()
{
int k=0;char ch=gt;
while(ch<'-')ch=gt;
while(ch>'-')k=k*10+ch-'0',ch=gt;
return k;
}
int pr[]={469762049,998244353,1004535809};
const int md=1e9+7,YL=md;
inline ll ksm(ll a,ll b,ll p)
{
ll r=1;a%=p;
while(b){if(b&1)r=r*a%p;a=a*a%p,b>>=1;}
return r;
}
int R[maxn];
struct FFT
{
int G,P,A[maxn];
void NTT(int* a,int n,int f)
{
for (int i=0;i<n;i++)if(i<R[i])swap(a[i],a[R[i]]);
for (int i=1;i<n;i<<=1)
{
int gn=ksm(G,(P-1)/(i<<1),P);
for(int j=0;j<n;j+=(i<<1))
{
int g=1,x,y;
for (int k=0;k<i;k++,g=1ll*g*gn%P)
{
x=a[j+k],y=1ll*g*a[j+k+i]%P;
a[j+k]=(x+y)%P,a[j+k+i]=(x+P-y)%P;
}
}
}
if(f==1)return;
int nv=ksm(n,P-2,P);reverse(a+1,a+n);
for(int i=0;i<n;i++)a[i]=1ll*a[i]*nv%P;
}
}fft[3];
int F[maxn],G[maxn],B[maxn],deg1,deg2,deg;
ll ans[maxn];
ll inv(ll n,ll p){return ksm(n % p,p - 2,p);}
ll mul(ll a,ll b,ll p)
{
ll re=0;
for(;b;b>>=1,a=(a+a)%p)
if(b&1)re=(re+a)%p;
return re;
}
void CRT()
{
deg=deg1+deg2;
ll a,b,c,t,k,M=1ll*pr[0]*pr[1];
ll inv1=inv(pr[1],pr[0]),inv0=inv(pr[0],pr[1]),inv3=inv(M%pr[2],pr[2]);
for(int i=0;i<=deg;i++)
{
a=fft[0].A[i],b=fft[1].A[i],c=fft[2].A[i];
t=(mul(a*pr[1]%M,inv1,M)+mul(b*pr[0]%M,inv0,M))%M;
k=((c-t%pr[2])%pr[2]+pr[2])%pr[2]*inv3%pr[2];
ans[i]=((k%md)*(M%md)%md+t%md)%md;
}
}
void pre()
{
int n=1,L=0;
while(n<=(deg1+deg2))n<<=1,L++;
for (int i=1;i<n;i++)R[i]=(R[i>>1]>>1)|((i&1)<<(L-1));
for (int u=0;u<=2;u++)
{
fft[u].G=3;fft[u].P=pr[u];
for(int i=0;i<=deg1;i++)fft[u].A[i]=F[i];
for(int i=0;i<=deg2;i++)B[i]=G[i];
for(int i=deg2+1;i<n;i++)B[i]=0;
fft[u].NTT(fft[u].A,n,1);fft[u].NTT(B,n,1);
for(int i=0;i<n;i++)fft[u].A[i]=1ll*fft[u].A[i]*B[i]%pr[u];
fft[u].NTT(fft[u].A,n,-1);
}
}
void get_mul(int *a,int *b,int *c,int n,int m)
{
deg1=n;deg2=m;
for(int i=0;i<=deg1;++i)F[i]=a[i];
for(int i=0;i<=deg2;++i)G[i]=b[i];
pre();CRT();
for(int i=0;i<=deg;++i)c[i]=ans[i];
}
const int N=1e6+7;
inline int ksm(int a,int k){int r=1;while(k){if(k&1)r=1ll*a*r%YL;a=1ll*a*a%YL,k>>=1;}return r;}
int fac[N],fnv[N],ma[N],as[N];
inline int C(int x,int y){return y>x?0:1ll*fac[x]*fnv[y]%YL*fnv[x-y]%YL;}
inline int MO(const int &a){return a>=YL?a-YL:a;}
int a[N],b[N],c[N];
int main()
{
// File("conut");
int n=in();fac[0]=fnv[0]=1;
for(int i=1;i<=n+1;++i)fac[i]=1ll*fac[i-1]*i%YL;
fnv[n+1]=ksm(fac[n+1],YL-2);
for(int i=n;i;--i)fnv[i]=1ll*fnv[i+1]*(i+1)%YL;
int l=1,r=n+1;
for(int i=1,u;i<=n+1;++i)
{
u=in();
if(ma[u])l=ma[u],r=i;
ma[u]=i;
}
for(int i=1;i<=n;++i)as[i]=C(n,i);
int l1=l-1,l2=r-l,l3=n-r+1;
for(int i=0;i<=l1;++i)a[i]=C(l1,i);
for(int i=1;i<=l2;++i)b[i]=C(l2,i);
get_mul(a,b,b,l1,l2);
Set(a),Set(ans),Set(F),Set(G),Set(fft);
for(int i=0;i<=l3;++i)a[i]=C(l3,i);
get_mul(a,b,b,l3,l1+l2);
for(int i=1;i<=n;++i)as[i+1]=MO(as[i+1]+b[i]);
for(int i=1;i<=n+1;++i)printf("%d\n",as[i]);
return 0;
}

noi.acNOIP模拟赛5-count的更多相关文章

  1. [NOI P模拟赛] 传统艺能(子序列自动机、矩阵乘法,线段树)

    (2:00)OID:"完了,蓝屏了!"(代码全消失) 众人欢呼 OID:开机,"原题测试--" (30min later)OID 开始传统艺能: " ...

  2. 【NOI P模拟赛】最短路(树形DP,树的直径)

    题面 给定一棵 n n n 个结点的无根树,每条边的边权均为 1 1 1 . 树上标记有 m m m 个互不相同的关键点,小 A \tt A A 会在这 m m m 个点中等概率随机地选择 k k k ...

  3. HDU 3月ACM模拟赛T10 COUNT

    题面 //来自TKJ的友好提供 ^_^ 然后我又被卡了半天不知道怎么转移N3 于是听CWY给我讲 终于会了 (虽然他讲的不是很清楚QAQ 但是凭着我们之间根本不存在的默契竟然达成了心智联通) 重点在于 ...

  4. 【XJOI】【NOI考前模拟赛7】

    DP+卡常数+高精度/  计算几何+二分+判区间交/  凸包 首先感谢徐老师的慷慨,让蒟蒻有幸膜拜了学军的神题.祝NOI2015圆满成功 同时膜拜碾压了蒟蒻的众神QAQ 填填填 我的DP比较逗比……( ...

  5. 2018/3/13 noiρ[rəʊ]模拟赛 125分

    T1 60分暴力,水分也不会水,打表也不会打,正解是不可能写正解的,这辈子都写不出来正解的,虽然是zz题但是也拿不到分这样子. 正解:(啥?正解是sb组合数?这都他娘的想不到,真鸡儿丢人我自杀吧.) ...

  6. NOI.ac模拟赛20181021 ball sequence color

    T1 ball 可以发现每次推动球时,是将每个球的位置 −1-1−1 ,然后把最左边的球放到 P−1P-1P−1 处. 记个 −1-1−1 次数,再用set维护就好了. #include <bi ...

  7. NOI.ac 模拟赛20181103 排队 翘课 运气大战

    题解 排队 20% 1≤n≤20,1≤x,hi≤201\le n\le 20, 1\le x,h_i\le 201≤n≤20,1≤x,hi​≤20 随便暴力 50% 1≤n≤2000,1≤x,hi≤1 ...

  8. Newnode's NOI(P?)模拟赛 第二题 dp决策单调优化

    其实直接暴力O(n3)DP+O2O(n^3)DP+O_2O(n3)DP+O2​优化能过- CODE O(n3)O(n^3)O(n3) 先来个O(n3)O(n^3)O(n3)暴力DP(开了O2O_2O2 ...

  9. Newnode's NOI(P?)模拟赛 第三题 (主席树优化建图 + tarjan)

    题目/题解戳这里 这道题题目保证a,b,ca,b,ca,b,c各是一个排列-mdzz考场上想到正解但是没看到是排列,相等的情况想了半天-然后写了暴力60分走人- 由于两两间关系一定,那么就是一个竞赛图 ...

随机推荐

  1. 【SIKIA计划】_05_Unity5.3开发2D游戏笔记

    一.界面基本操作 01.Project基本分类[Audios]音效[Material]材质[Prefabs]预制[Scenes]场景[Scripts]脚本[Sprites]精灵 02.Project丶 ...

  2. 【厚积薄发】Crunch压缩图片的AssetBundle打包

    这是第133篇UWA技术知识分享的推送.今天我们继续为大家精选了若干和开发.优化相关的问题,建议阅读时间10分钟,认真读完必有收获. UWA 问答社区:answer.uwa4d.com UWA QQ群 ...

  3. Received non-all-whitespace CHARACTERS or CDATA event in nextTag(). ,无法整齐打印验证错误。 解析XML文档出现的问题

    在启动keyCloak,想要在standAlone模式下切换数据库,修改standAlone.xml文件时. 在bin/目录下启动standAlone模式出现错误: 10:07:24,799 INFO ...

  4. NO.2:自学tensorflow之路------BP神经网络编程

    引言 在上一篇博客中,介绍了各种Python的第三方库的安装,本周将要使用Tensorflow完成第一个神经网络,BP神经网络的编写.由于之前已经介绍过了BP神经网络的内部结构,本文将直接介绍Tens ...

  5. chattr和lsattr命令详解

    基础命令学习目录首页 原文链接:http://www.ha97.com/5172.html PS:有时候你发现用root权限都不能修改某个文件,大部分原因是曾经用chattr命令锁定该文件了.chat ...

  6. 第十次ScrumMeeting博客

    第十次ScrumMeeting博客 本次会议于11月5日(日)22时整在新主楼G座2楼召开,持续20分钟. 与会人员:刘畅.辛德泰.窦鑫泽.张安澜.赵奕.方科栋. 特邀嘉宾:陈彦吉学长. 1. 每个人 ...

  7. 兼容所有浏览器的旋转效果-IE滤镜Matrix和CSS3transform

    在现代浏览器中使用CSS3的transform样式即可轻松搞定,但是对于国内IE浏览器(特别是7,8)还占有较大份额的情况下,兼容性还是必须要考虑的,所以也特意记录下IE旋转滤镜的使用. 在IE下的旋 ...

  8. 课堂实践ASL博客

    实践博客 二分法查找元素 1.首先定义三个位置min,mid,max 2.每次从所有元素所处位置的中间开始查找(所有元素必须以由小及大顺序排列完毕) 3.当中间元素大于所查找元素时,从中间元素(mid ...

  9. 深入理解Java类加载器(1)

    类加载器概述: java类的加载是由虚拟机来完成的,虚拟机把描述类的Class文件加载到内存,并对数据进行校验,解析和初始化,最终形成能被java虚拟机直接使用的java类型,这就是虚拟机的类加载机制 ...

  10. 014 C语言文法定义与C程序的推导过程