BZOJ4133 : Answer的排队
设$f[i][j]$表示考虑前$i$个人,第$i$个人在前$i$个人中排名为$j$的方案数。
对于大小关系相同的一段,转移可以看成求$k$次前/后缀和,任意一项对另一项的贡献仅和其下标差值有关,FFT加速即可。
时间复杂度$O(mn\log n)$。
#include<cstdio>
#include<cmath>
#include<algorithm>
using namespace std;
const int N=65555,M=32768,P=1000000007;
int n,m,i,j,k,t,o,len,L,R,a[30],b[N],f[N*3],ans,g[N],v[N],fin[N],fac[N],inv[N],pos[N];
inline void up(int&a,int b){(a+=b)>=P&&(a-=P);}
inline int C(int n,int m){return 1LL*fac[n]*inv[m]%P*inv[n-m]%P;}
namespace FFT{
struct comp{
long double r,i;comp(long double _r=0,long double _i=0){r=_r;i=_i;}
comp operator+(const comp&x){return comp(r+x.r,i+x.i);}
comp operator-(const comp&x){return comp(r-x.r,i-x.i);}
comp operator*(const comp&x){return comp(r*x.r-i*x.i,r*x.i+i*x.r);}
comp conj(){return comp(r,-i);}
}A[N],B[N];
int a0[N],b0[N],a1[N],b1[N];
const long double pi=acos(-1.0);
void FFT(comp a[],int n,int t){
for(int i=1;i<n;i++)if(i<pos[i])swap(a[i],a[pos[i]]);
for(int d=0;(1<<d)<n;d++){
int m=1<<d,m2=m<<1;
long double o=pi*2/m2*t;comp _w(cos(o),sin(o));
for(int i=0;i<n;i+=m2){
comp w(1,0);
for(int j=0;j<m;j++){
comp&A=a[i+j+m],&B=a[i+j],t=w*A;
A=B-t;B=B+t;w=w*_w;
}
}
}
if(t==-1)for(int i=0;i<n;i++)a[i].r/=n;
}
void mul(int*a,int*b,int*c,int k){
int i,j;
for(i=0;i<k;i++)A[i]=comp(a[i],b[i]);
FFT(A,k,1);
for(i=0;i<k;i++){
j=(k-i)&(k-1);
B[i]=(A[i]*A[i]-(A[j]*A[j]).conj())*comp(0,-0.25);
}
FFT(B,k,-1);
for(i=0;i<k;i++)c[i]=((long long)(B[i].r+0.5))%P;
}
void mulmod(int*a,int*b,int*c,int k){
int i;
for(i=0;i<k;i++)a0[i]=a[i]/M,b0[i]=b[i]/M;
for(mul(a0,b0,a0,k),i=0;i<k;i++){
c[i]=1LL*a0[i]*M*M%P;
a1[i]=a[i]%M,b1[i]=b[i]%M;
}
for(mul(a1,b1,a1,k),i=0;i<k;i++){
c[i]=(a1[i]+c[i])%P,a0[i]=(a0[i]+a1[i])%P;
a1[i]=a[i]/M+a[i]%M,b1[i]=b[i]/M+b[i]%M;
}
for(mul(a1,b1,a1,k),i=0;i<k;i++)c[i]=(1LL*M*(a1[i]-a0[i]+P)+c[i])%P;
}
}
inline void solve(int len,int K){
int i,j,k;
for(k=1;k<=len;k<<=1);k<<=1;
j=__builtin_ctz(k)-1;
for(i=0;i<k;i++)pos[i]=pos[i>>1]>>1|((i&1)<<j);
for(i=0;i<=len;i++)v[i]=C(i+K-1,K-1);
for(g[0]=0;i<k;i++)v[i]=g[i]=0;
FFT::mulmod(g,v,fin,k);
for(i=1;i<=len;i++)g[i]=fin[i];
}
int main(){
scanf("%d%d",&n,&m);
for(fac[0]=i=1;i<=n*2;i++)fac[i]=1LL*fac[i-1]*i%P;
for(inv[0]=inv[1]=1,i=2;i<=n*2;i++)inv[i]=1LL*(P-P/i)*inv[P%i]%P;
for(i=2;i<=n*2;i++)inv[i]=1LL*inv[i-1]*inv[i]%P;
for(i=1;i<=m;i++)scanf("%d",&a[i]);
for(i=1;i<m;i++)for(j=a[i];j<a[i+1];j++)b[j]=i&1;
for(i=a[2],L=1+N,f[R=i+N]=1;i<n;i=j){
for(j=i;j<n&&b[i]==b[j];j++);
t=j-i;
for(k=L;k<=R;k++)g[k-L+1]=f[k];
len=R-L+1;
if(!b[i])reverse(g+1,g+len+1);
solve(len,t);
if(!b[i])reverse(g+1,g+len+1);
for(k=L;k<=R;k++)f[k]=g[k-L+1];
b[i]?L-=t:R+=t;
}
for(i=L;i<=R;i++)up(ans,f[i]);
return printf("%d",ans),0;
}
BZOJ4133 : Answer的排队的更多相关文章
- bzoj AC倒序
Search GO 说明:输入题号直接进入相应题目,如需搜索含数字的题目,请在关键词前加单引号 Problem ID Title Source AC Submit Y 1000 A+B Problem ...
- C++ 事件驱动型银行排队模拟
最近重拾之前半途而废的C++,恰好看到了<C++ 实现银行排队服务模拟>,但是没有实验楼的会员,看不到具体的实现,正好用来作为练习. 模拟的是银行的排队叫号系统,所有顾客以先来后到的顺序在 ...
- bzoj 2729: [HNOI2012]排队
2729: [HNOI2012]排队 Time Limit: 10 Sec Memory Limit: 128 MB Description 某中学有 n 名男同学,m 名女同学和两名老师要排队参加体 ...
- bzoj 2141: 排队
2141: 排队 Time Limit: 4 Sec Memory Limit: 259 MB Description 排排坐,吃果果,生果甜嗦嗦,大家笑呵呵.你一个,我一个,大的分给你,小的留给我, ...
- SPOJ GSS3 Can you answer these queries III[线段树]
SPOJ - GSS3 Can you answer these queries III Description You are given a sequence A of N (N <= 50 ...
- 可重入锁 公平锁 读写锁、CLH队列、CLH队列锁、自旋锁、排队自旋锁、MCS锁、CLH锁
1.可重入锁 如果锁具备可重入性,则称作为可重入锁. ========================================== (转)可重入和不可重入 2011-10-04 21:38 这 ...
- hdu 1872(看病要排队)(优先队列)
看病要排队 Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submi ...
- Stack Overflow is a question and answer site
http://stackoverflow.com/ _ Stack Overflow is a question and answer site for professional and enthus ...
- 赴美工作常识(Part 6 - 绿卡排队)
上一篇<赴美工作常识(Part 5 - 绿卡优先级)>解释完排队的优先级是怎么确定的,以及 PERM 和 I–140 表的意义,接下来就要解释一下队具体是怎么排的以及排到之后的 I–485 ...
随机推荐
- Quartz.NET作业调度框架的简单应用
概述 Quartz.NET是一个开源的作业调度框架,非常适合在平时的工作中,定时轮询数据库同步,定时邮件通知,定时处理数据等. Quartz.NET允许开发人员根据时间间隔(或天)来调度作业.它实现了 ...
- jquery实时监听输入框值变化
在做web开发时候很多时候都需要即时监听输入框值的变化,以便作出即时动作去引导浏览者增强网站的用户体验感.而采用onchange时间又往往是在输入框失去焦点(onblur)时候触发,有时候并不能满足条 ...
- 【BZOJ3782】上学路线
题解: 这个容斥以前做过 到i点的所有方案显然是个组合数 然后要减去不合法的方案数 我们可以考虑成减去到每个障碍点为第一次遇到的障碍然后之后乱走就可以了 因为模数不是质数,所以crt合并
- jxoi2017
题解: 并不知道题目顺序就按照难度排序了 [JXOI2017]加法 这是一道很简单的贪心 最小值最大二分答案 然后我们可以从左向右考虑每一个位置 如果他还需要+A 我们就从能覆盖它的区间中挑一个最右的 ...
- Windows下80端口被进程System占用的解决方法
最近电脑时不时就发生了80端口被占用的情况,简单百度解决后,当重启电脑的时候又发生被占用的情况.今天非常幸运的是,发生了80端口和8080端口都被占用了情况,忍无可忍决定下定决心解决这个坑爹的问题,经 ...
- 基于AspNet Core2.0 开发框架,包含简单的个人博客Demo
大家好,最近离职了,利用闲暇时间就捣鼓了一个基于AspNet Core开发框架,分享出来希望能给AspNet Core学者带来一些帮助,同时也能跟大家一起学习.当然了,由于我的个人技术及经验的有限,框 ...
- 【Android】jar包Proguard混淆方法
本文章的前提条件是,读者已经掌握了正确导出jar包的技能. 1.拷贝Android项目中“proguard.cfg”文件到你指定的位置,并改名为“proguard.pro”,此步是为proguardg ...
- Flink--3种分区方式
partitionByHash //TODO partitionByHash val data = new mutable.MutableList[(Int, Long, String)] data. ...
- Linux安装Tomcat-Nginx-FastDFS-Redis-Solr-集群——【第九集-补充-之安装jdk】
1,安装JDK,本来想安装jdk8的,但是考虑到tomcat安装的是tomcat7,怕出现版本不兼容的情况,就改安装jdk7 去官网下载jdk-7u80-linux-x64.tar.gz的二进制文件, ...
- P1026 统计单词个数 区间dp
题目描述 给出一个长度不超过200200的由小写英文字母组成的字母串(约定;该字串以每行2020个字母的方式输入,且保证每行一定为2020个).要求将此字母串分成kk份(1<k \le 401& ...