CF848E Days of Floral Colours——DP+多项式求逆/分治NTT
官方题解:
http://codeforces.com/blog/entry/54233
就是由简入繁
1.序列处理,只考虑一个半圆
2.环形处理(其实这个就是多了旋转同构)
然后基于分割线邻居的跨越与否,分类讨论
g->没有分割线方案数(其实也可以变成贡献,但是太简单,之后乘上(i+0/1/2)也方便)
f0->有分割线,两边都没有选所有情况的贡献的和
f1->有分割线,两边选择了一个所有情况的贡献的和
f2->有分割线,两边都选择了所有情况的贡献的和
最后对于环
考虑除了中间割线,顺时针第一个割线的位置i,再对于跨越与否分4种情况讨论。可以逆时针旋转(i-2)个
对于式子,可以分治FFT
或者大力解二元方程,变成多项式求逆
代码:
#include<bits/stdc++.h>
#define reg register int
#define il inline
#define int long long
#define numb (ch^'0')
using namespace std;
typedef long long ll;
template<class T>il void rd(T &x){
char ch;x=;bool fl=false;
while(!isdigit(ch=getchar()))(ch=='-')&&(fl=true);
for(x=numb;isdigit(ch=getchar());x=x*+numb);
(fl==true)&&(x=-x);
}
template<class T>il void ot(T x){
x/?ot(x/):putchar(x%+'');
}
template<class T>il void prt(T a[],int st,int nd){
for(reg i=st;i<=nd;++i) printf("%lld ",a[i]);putchar('\n');
}
namespace Miracle{
const int N=*+;
const int mod=;
const int G=;
const int GI=;
int n;
ll f0[N],f1[N],f2[N];
ll g[N],g0[N],g1[N],g2[N];
ll x3g2[N],g12[N],ix3g2[N];
ll ni[N],t[N],p[N],l[N],q[N];
ll qm(ll x,ll y){
ll ret=;
while(y){
if(y&) ret=(ll)ret*x%mod;
x=(ll)x*x%mod;
y>>=;
}
return ret;
}
int rev[N];
void NTT(ll *f,int n,int typ){
// cout<<n<<endl;
for(reg i=;i<n;++i){
if(i<rev[i]) swap(f[i],f[rev[i]]);
}
for(reg p=;p<=n;p<<=){
ll gen;
if(typ==) gen=qm(G,(mod-)/p);
else gen=qm(GI,(mod-)/p);
for(reg l=;l<n;l+=p){
ll buf=;
for(reg k=l;k<l+p/;++k){
ll tmp=f[k+p/]*buf%mod;
f[k+p/]=(f[k]-tmp+mod)%mod;
f[k]=(f[k]+tmp)%mod;
buf=buf*gen%mod;
}
}
}
}
void calc(ll *f,ll *g,int n){
for(reg i=;i<n;++i){
rev[i]=(rev[i>>]>>)|((i&)?n>>:);
}
NTT(f,n,);NTT(g,n,);
for(reg i=;i<n;++i) f[i]=f[i]*g[i]%mod;
NTT(f,n,-);
ll iv=qm(n,mod-);
for(reg i=;i<n;++i) f[i]=f[i]*iv%mod;
}
void add(ll *f,ll *g,int n){//n is max(len f,len g)
for(reg i=;i<n;++i){
f[i]=(f[i]+g[i])%mod;
}
}
void sub(ll *f,ll *g,int n){
for(reg i=;i<n;++i){
f[i]=(f[i]-g[i]+mod)%mod;
}
}
void inv(ll *f,ll *g,int n){
// cout<<" inv "<<n<<endl;
if(n==){
g[]=qm(f[],mod-);return;
}
inv(f,g,n>>);
for(reg i=;i<n;++i) t[i]=f[i];
for(reg i=n;i<*n;++i) t[i]=;
for(reg i=;i<*n;++i){
rev[i]=(rev[i>>]>>)|((i&)?n:);
}
NTT(t,*n,);NTT(g,*n,);
for(reg i=;i<*n;++i){
g[i]=(+mod-t[i]*g[i]%mod)%mod*g[i]%mod;
}
NTT(g,*n,-);
ll iv=qm(*n,mod-);
for(reg i=;i<n;++i) g[i]=g[i]*iv%mod;
for(reg i=n;i<*n;++i) g[i]=;
}
void tran(ll *f,int len,int n){//warning!! bac to length=length+len
for(reg i=n-+len;i>=len;--i){
f[i]=f[i-len];
}
for(reg i=;i<len;++i) f[i]=;
}
int main(){
rd(n);
g[]=;g[]=;g[]=;g[]=;
int lp;
for(lp=;lp<=n+n+;lp<<=);//warning!! biggest length
for(reg i=;i<=n;++i){
g[i]=(g[i-]+g[i-])%mod;
}
for(reg i=;i<=n;++i){
g0[i]=g[i]*i%mod*i%mod;
g1[i]=g[i]*(i+)%mod*(i+)%mod;
g2[i]=g[i]*(i+)%mod*(i+)%mod;
}
l[]=;
// cout<<lp<<endl;
// x3g2[0]=1;
// memcpy(p,g2,sizeof g2);tran(p,3,n+1);
// sub(x3g2,p,lp);
// inv(x3g2,ix3g2,lp);
// cout<<" ix3g2 "<<endl;
// prt(ix3g2,0,lp-1); memcpy(p,g2,sizeof g2);
tran(p,,n+);
sub(l,p,lp); memcpy(p,g0,sizeof g0);
tran(p,,n+);
sub(l,p,lp); memcpy(p,g0,sizeof g0);
memcpy(q,g2,sizeof g2);
calc(p,q,lp);
tran(p,,lp);
add(l,p,lp); memcpy(p,g1,sizeof g1);
memcpy(q,g1,sizeof g1);
calc(p,q,lp);
tran(p,,lp);
sub(l,p,lp); inv(l,ni,lp);
for(reg i=n+;i<lp;++i) ni[i]=;
//////////////////////inv 1
memcpy(l,g0,sizeof g0); memcpy(p,g0,sizeof g0);
memcpy(q,g2,sizeof g2);
calc(p,q,lp);
tran(p,,lp);
sub(l,p,lp); memcpy(p,g1,sizeof g1);
memcpy(q,g1,sizeof g1);
calc(p,q,lp);
tran(p,,lp);
add(l,p,lp); for(reg i=n+;i<lp;++i) l[i]=;
calc(l,ni,lp);
memcpy(f0,l,sizeof l);
for(reg i=n+;i<lp;++i) f0[i]=;
/////////////////////f0
memset(l,,sizeof l);
l[]=;
memcpy(p,g2,sizeof g2);
tran(p,,n+);
sub(l,p,lp); memset(ni,,sizeof ni);
inv(l,ni,lp);
for(reg i=n+;i<lp;++i) ni[i]=;
// prt(ni,0,lp-1); memcpy(l,g1,sizeof g1);
memcpy(p,g1,sizeof g1);
tran(p,,n+);
// cout<<" ll "<<endl;
// prt(p,0,lp-1);
memcpy(q,f0,sizeof f0);
//prt(q,0,lp-1);
calc(p,q,lp); add(l,p,lp); for(reg i=n+;i<lp;++i) l[i]=;
memcpy(p,ni,sizeof ni);
calc(l,p,lp); memcpy(f1,l,sizeof l);
for(reg i=n+;i<lp;++i) f1[i]=;
///////////////////////f1 memcpy(l,g2,sizeof g2);
memcpy(p,g1,sizeof g1);
tran(p,,n+);
memcpy(q,f1,sizeof f1);
calc(p,q,lp);
add(l,p,lp); for(reg i=n+;i<lp;++i) l[i]=;
// memcpy(p,ni,sizeof ni);
calc(l,ni,lp); memcpy(f2,l,sizeof l);
/////////////////////f2
// cout<<"f0 "<<endl;
// for(reg i=0;i<n;++i){
// cout<<f0[i]<<" ";
// }cout<<endl;
// cout<<"f1 "<<endl;
// for(reg i=0;i<n;++i){
// cout<<f1[i]<<" ";
// }cout<<endl;
// cout<<"f2 "<<endl;
// for(reg i=0;i<n;++i){
// cout<<f2[i]<<" ";
// }cout<<endl;
ll ans=(ll)n*(g[n-]+g[n-])%mod*(n-)%mod*(n-)%mod;
for(reg i=;i<=n;++i){
ll tmp=;
tmp=(tmp+g[i-]*f0[n-i]%mod*(i-)%mod*(i-)%mod)%mod;
if(i>&&i<n) tmp=(tmp+g[i-]*f1[n-i-]%mod*%mod*(i-)%mod*(i-)%mod)%mod;
if(i>&&i<n-) tmp=(tmp+g[i-]*f2[n-i-]%mod*(i-)%mod*(i-)%mod)%mod;
tmp=tmp*(i-)%mod;
ans=(ans+tmp)%mod;
}
cout<<ans;
return ;
} }
signed main(){
Miracle::main();
return ;
} /*
Author: *Miracle*
Date: 2019/2/27 15:57:21
*/
总结:
0.拆开,只考虑一个半圆
1.由于贡献是根据割线统计的,推DP式子时候根据割线的跨越与否进行统计
CF848E Days of Floral Colours——DP+多项式求逆/分治NTT的更多相关文章
- BZOJ 3456: 城市规划(dp+多项式求逆)
传送门 解题思路 这道题就是求带标号的无向连通图个数,首先考虑\(O(n^2)\)的做法,设\(f_i\)表示有\(i\)个节点的无向连通图个数,那么考虑容斥,先把所有的无向图求出,即为\(2^{C( ...
- 【洛谷4238】 多项式求逆(NTT,分治)
前言 多项式求逆还是爽的一批 Solution 考虑分治求解这个问题. 直接每一次NTT一下就好了. 代码实现 #include<stdio.h> #include<stdlib.h ...
- 多项式求逆/分治FFT 学习笔记
一.多项式求逆 给定一个多项式 \(F(x)\),请求出一个多项式 \(G(x)\), 满足 \(F(x) * G(x) \equiv 1 ( \mathrm{mod\:} x^n )\).系数对 \ ...
- 【bzoj3456】城市规划 dp+多项式求逆
Description 刚刚解决完电力网络的问题, 阿狸又被领导的任务给难住了. 刚才说过, 阿狸的国家有n个城市, 现在国家需要在某些城市对之间建立一些贸易路线, 使得整个国家的任意两个城市都直接或 ...
- Luogu4238 【模板】多项式求逆(NTT)
http://blog.miskcoo.com/2015/05/polynomial-inverse 好神啊! B(x)=B'(x)·(2-A(x)B'(x)) 注意ntt的时候防止项数溢出,即将多项 ...
- 洛谷P4238 【模板】多项式求逆(NTT)
传送门 学习了一下大佬的->这里 已知多项式$A(x)$,若存在$A(x)B(x)\equiv 1\pmod{x^n}$ 则称$B(x)$为$A(x)$在模$x^n$下的逆元,记做$A^{-1} ...
- bzoj 3456 城市规划 多项式求逆+分治FFT
城市规划 Time Limit: 40 Sec Memory Limit: 256 MBSubmit: 1091 Solved: 629[Submit][Status][Discuss] Desc ...
- hdu 5730 Shell Necklace [分治fft | 多项式求逆]
hdu 5730 Shell Necklace 题意:求递推式\(f_n = \sum_{i=1}^n a_i f_{n-i}\),模313 多么优秀的模板题 可以用分治fft,也可以多项式求逆 分治 ...
- BZOJ 3456: 城市规划 与 多项式求逆算法介绍(多项式求逆, dp)
题面 求有 \(n\) 个点的无向有标号连通图个数 . \((1 \le n \le 1.3 * 10^5)\) 题解 首先考虑 dp ... 直接算可行的方案数 , 容易算重复 . 我们用总方案数减 ...
随机推荐
- js值----你所不知道的JavaScript系列(6)
1.数组 在 JavaScript 中,数组可以容纳任何类型的值,可以是字符串.数字.对象(object),甚至是其他数组(多维数组就是通过这种方式来实现的) .----<你所不知道的JavaS ...
- BGFX 渲染引擎中着色器代码的调试方法
在实时渲染的图形开发中,着色器代码(Shader)越来越复杂,于是单纯的靠经验和不断试错的开发和调试方法早已不能满足实际需求.使用调试工具进行调试,成为开发中重要的方法.Bgfx 是一款跨平台.抽象封 ...
- NSCache的简单使用
简介 1)NSCache 是苹果官方提供的缓存类,用法与 NSMutableDictionary 的用法很相似,在 AFNetworking 和 SDWebImage 中,使用它来管理缓存. 2)NS ...
- Echarts学习求教
有没有人用过百度的Echarts?刚开始接触,下面这段代码怎么理解啊,新手求指教: myChart.showLoading();$.get('data/asset/data/les-miserable ...
- 20135218 实践四 ELF文件格式分析
一 :概述 ELF全称Executable and Linkable Format,可执行连接格式,ELF格式的文件用于存储Linux程序.ELF文件(目标文件)格式主要三种: (1)可重定向文件:文 ...
- 20135316Linux内核学习笔记第六周
20135316王剑桥<Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC 1000029000 一.进程控制块PCB--task_ ...
- BugPhobia进阶篇章:功能规格说明书
0x01 :特别鸣谢 首先特别鸣谢<构建之法>中并没有给出固定化格式的功能规格说明书的样例,因此在此次的说明书中将尽可能用生动形象的例子展示软件交互阐释 因此受到它本身的启发,此次团队功能 ...
- 开源通用爬虫框架YayCrawler-框架的运行机制
这一节我将向大家介绍一下YayCrawler的运行机制,首先允许我上一张图: 首先各个组件的启动顺序建议是Master.Worker.Admin,其实不按这个顺序也没关系,我们为了讲解方便假定是这个启 ...
- VMware 桥接 Bridge 复制物理网络连接状态
https://zhidao.baidu.com/question/535593443.html 意思就是说,VM上使用的是虚拟的网卡,也就是说VM虚拟机上的网卡不是真实存在的,而桥接还有其他的网路链 ...
- Notepad++和Sublime单词首字符大小写转化问题