[SDWC2018 Day1]网格
前言
学了容斥与二项式反演,也该写写题了
题目介绍
题目网址
题意简介
现在有个人,要用MMM步从(0,0)(0,0)(0,0)跳到(Tx,Ty)(T_x,T_y)(Tx,Ty),每次只能向右上方跳(即坐标值只能加),不能在原地跳
给出一些限制:给出KKK个限制kik_iki,表示两个坐标不能同时加kik_iki。给出一个数GGG,保证所有kik_iki都是GGG的倍数,求方案数(模109+710^9+7109+7)
数据范围
Tx,Ty≤106,Mx≤Tx,My≤TyT_x,T_y\le10^6,M_x\le T_x,M_y\le T_yTx,Ty≤106,Mx≤Tx,My≤Ty
R≤1000,10000≤G≤50000,K≤50R\le 1000,10000\le G\le50000,K\le50R≤1000,10000≤G≤50000,K≤50
题解
K=0K=0K=0
先考虑K=0K=0K=0的情况
两个维度,都是10610^6106级别的,一起做一定不好做
然后发现除了“两维不能同时停在原地”这个限制以外,两维是独立的
考虑对于一维,我们已知其长度TTT以及单步最大距离MMM
求不违反规则恰好走xxx步的方案数
直接dpdpdp复杂度是Θ(TMR)\Theta(TMR)Θ(TMR)的,显然不行
我们发现至少违反aaa次规则恰好走RRR步的方案数很好求
设calc(a)calc(a)calc(a)为至少违反aaa次规则的方案数,我们发现可以选aaa步,让这些步一开始就有M+1M+1M+1的值,那么其无论再加多少都一定是违反规则的
那么就得出calc(a)calc(a)calc(a)的式子:calc(a)=(Ra)(T−(M+1)∗a+R−1R−1)calc(a)=\binom{R}{a}\binom{T-(M+1)*a+R-1}{R-1}calc(a)=(aR)(R−1T−(M+1)∗a+R−1)
预处理组合数后计算calc(a)calc(a)calc(a)单次Θ(1)\Theta(1)Θ(1)
考虑容斥,容易发现我们要求的答案就是∑i=0R(−1)icalc(i)\sum_{i=0}^R(-1)^icalc(i)i=0∑R(−1)icalc(i)
所以对于一维的答案的复杂度是Θ(R)\Theta(R)Θ(R)的,那么我们把两维都求出来
我们发现,两维的乘积的结果并不是我们想要的恰好RRR步,而是至多RRR步
所以我们如果要合并,我们不能直接相乘
给定T,MT,MT,M,设L(R)L(R)L(R)为给至多走RRR步的方案数,E(R)E(R)E(R)为恰好走RRR步的方案数
L(R)=∑i=0R(Ri)E(i)L(R)=\sum_{i=0}^R\binom{R}{i}E(i)L(R)=i=0∑R(iR)E(i)
二项式反演
E(R)=∑i=0R(−1)R−i(Ri)L(i)E(R)=\sum_{i=0}^R(-1)^{R-i}\binom{R}{i}L(i)E(R)=i=0∑R(−1)R−i(iR)L(i)
然后发现求一次E(R)E(R)E(R)是Θ(R2)\Theta(R^2)Θ(R2)的,比较优越
K≠0K\neq0K̸=0
然后我们考虑有KKK限制的情况
我们发现我们要求的是不违反限制的情况,但是并不好求
又发现,至少违反nnn次数的情况很好统计
同样考虑容斥,g(x)g(x)g(x)为至少违反xxx次的方案数,容易发现我们要求的就是∑i=0∞(−1)ig(i)\sum_{i=0}^{\infty}(-1)^ig(i)i=0∑∞(−1)ig(i)
我们先来思考iii的范围,由于kik_iki都是GGG的倍数,而G≥10000G\ge10000G≥10000,所以iii的取值范围是Θ(TG)=Θ(100)\Theta(\frac TG)=\Theta(100)Θ(GT)=Θ(100)的
考虑dpdpdp来统计ggg,定义fi,jf_{i,j}fi,j为至少违反jjj次、∑k=j∗G\sum k=j*G∑k=j∗G的方案数,容易发现第二维也是Θ(100)\Theta(100)Θ(100)的
fi,jf_{i,j}fi,j对答案的贡献系数即Tx−j∗G,Ty−j∗G,x−iT_x-j*G,T_y-j*G,x-iTx−j∗G,Ty−j∗G,x−i步并且没有任何限制的答案,通过前面K=0K=0K=0的部分的分析可以得知这部分的复杂度是Θ(Mx)\Theta(Mx)Θ(Mx)的,总复杂度大概是Θ(1000∗1000∗100∗100)\Theta(1000*1000*100*100)Θ(1000∗1000∗100∗100)的
貌似能过??而且跑的飞快
当然我们要科学的复杂度,只要预处理L(x)L(x)L(x)即可,我们发现TTT的取值因为jjj的不同只有Θ(100)\Theta(100)Θ(100)组,步数是Θ(R)\Theta(R)Θ(R)的,一次处理是Θ(R)\Theta(R)Θ(R)的
所以总复杂度为Θ(TGR2)\Theta(\frac TGR^2)Θ(GTR2)大约10810^8108左右,再加上根本跑不满,所以很容易就过了
代码
#include<cstdio>
#include<cctype>
#include<algorithm>
namespace fast_IO
{const int IN_LEN=10000000,OUT_LEN=10000000;char ibuf[IN_LEN],obuf[OUT_LEN],*ih=ibuf+IN_LEN,*oh=obuf,*lastin=ibuf+IN_LEN,*lastout=obuf+OUT_LEN-1;inline char getchar_(){return (ih==lastin)&&(lastin=(ih=ibuf)+fread(ibuf,1,IN_LEN,stdin),ih==lastin)?EOF:*ih++;}inline void putchar_(const char x){if(oh==lastout)fwrite(obuf,1,oh-obuf,stdout),oh=obuf;*oh++=x;}inline void flush(){fwrite(obuf,1,oh-obuf,stdout);}
}
using namespace fast_IO;
#define getchar() getchar_()
#define putchar(x) putchar_((x))
//#include<ctime>
#define rg register
typedef long long LL;
template <typename T> inline T max(const T a,const T b){return a>b?a:b;}
template <typename T> inline T min(const T a,const T b){return a<b?a:b;}
template <typename T> inline void mind(T&a,const T b){a=a<b?a:b;}
template <typename T> inline void maxd(T&a,const T b){a=a>b?a:b;}
template <typename T> inline T abs(const T a){return a>0?a:-a;}
template <typename T> inline void swap(T&a,T&b){T c=a;a=b;b=c;}
//template <typename T> inline void swap(T*a,T*b){T c=a;a=b;b=c;}
template <typename T> inline T gcd(const T a,const T b){if(!b)return a;return gcd(b,a%b);}
template <typename T> inline T lcm(const T a,const T b){return a/gcd(a,b)*b;}
template <typename T> inline T square(const T x){return x*x;};
template <typename T> inline void read(T&x)
{char cu=getchar();x=0;bool fla=0;while(!isdigit(cu)){if(cu=='-')fla=1;cu=getchar();}while(isdigit(cu))x=x*10+cu-'0',cu=getchar();if(fla)x=-x;
}
template <typename T> inline void printe(const T x)
{if(x>=10)printe(x/10);putchar(x%10+'0');
}
template <typename T> inline void print(const T x)
{if(x<0)putchar('-'),printe(-x);else printe(x);
}
const LL mod=1000000007;
inline void md(LL&x){if(x>=mod)x-=mod;}
LL fac[1000001],inv[1000001];
inline LL pow(LL x,LL y)
{LL res=1;for(;y;y>>=1,x=x*x%mod)if(y&1)res=res*x%mod;return res;
}
inline LL C(LL x,LL y){return fac[x]*inv[y]%mod*inv[x-y]%mod;}
inline void init()
{fac[0]=1;for(rg int i=1;i<=1000000;i++)fac[i]=fac[i-1]*i%mod;inv[1000000]=pow(fac[1000000],mod-2);for(rg int i=1000000;i>=1;i--)inv[i-1]=inv[i]*i%mod;
}
int T,Tx,Ty,Mx,My,R,G;
int K,k[51];
LL f[101][101],g[101];
LL calc[101][1001];
inline LL solve(const int x,const int step)
{LL res=0;for(rg int i=0;i<=step;i++){if((i&1)==(step&1))md(res+=calc[x][i]*C(step,i)%mod);else md(res+=mod-calc[x][i]*C(step,i)%mod);}return res;
}
int main()
{init();read(Tx),read(Ty),T=min(Tx,Ty),read(Mx),read(My),read(R),read(G);for(rg int i=0;G*i<=T;i++){const int tx=Tx-G*i,ty=Ty-G*i;for(rg int j=R;j>=0;j--){if(j*Mx<tx||j*My<ty)break;LL valx=0,valy=0;for(rg int step=0;step<=j&&(Mx+1)*step<=tx;step++)if(step&1)md(valx+=mod-C(j,step)*C(tx-(Mx+1)*step+j-1,j-1)%mod);else md(valx+=C(j,step)*C(tx-(Mx+1)*step+j-1,j-1)%mod);for(rg int step=0;step<=j&&(My+1)*step<=ty;step++)if(step&1)md(valy+=mod-C(j,step)*C(ty-(My+1)*step+j-1,j-1)%mod);else md(valy+=C(j,step)*C(ty-(My+1)*step+j-1,j-1)%mod);calc[i][j]=valx*valy%mod;}}read(K);for(rg int i=1;i<=K;i++)read(k[i]);std::sort(k+1,k+K+1);K=std::unique(k+1,k+K+1)-k-1;for(rg int i=1;i<=K;i++)k[i]/=G;f[0][0]=1,g[0]=solve(0,R);for(rg int i=1;G*i<=T;i++)for(rg int j=0;G*j<=T;j++){for(rg int kind=1;kind<=K;kind++)if(k[kind]<=j)md(f[i][j]+=f[i-1][j-k[kind]]);md(g[i]+=solve(j,R-i)*f[i][j]%mod);}LL ans=0;for(rg int i=0;G*i<=T;i++)if(i&1)md(ans+=mod-g[i]*C(R,i)%mod);else md(ans+=g[i]*C(R,i)%mod);print(ans);return flush(),0;
}
总结
这道题的非常巧妙,多次运用容斥与反演的技巧,值得深思
致谢:感谢yx2003在本题上对我的指导
[SDWC2018 Day1]网格相关推荐
- Loj #6060. 「2017 山东一轮集训 Day1 / SDWC2018 Day1」Set
原题是CF上的某题,但是还要输出方案....好鬼畜啊WWW 发现答案肯定是优先 xorsum^x1 + x1 最大,然后再优先x1最小(也就是 xorsum^x1 最大). 我们把xorsum二进制分 ...
- 【GDKOI】2021提高Day1
[GDKOI]2021提高Day1 2021 年广东省重点中学信息学冬令营 (GDKOI 2021) 提高组 第一试 2021 年 1 月 29 日 注意事项 严格按照题目所要求的格式进行输入.输出, ...
- 学习记录:UnityHDRP高清渲染管线学习 day1
附一张这本书的封面截图 ps:(我自我介绍一下吧,高中不好好学习去了大专,现在大一暑假在一家郑州互联网公司实习,月薪4500,转正之后是八千多(我觉得挺多了),其实并不是我多聪明,只是抓住了机会不想再 ...
- 技术图文:如何利用BigOne的API制作自动化交易系统--网格交易法
背景 前面,通过图文 如何利用 C# 爬取 ONE 的交易数据? 向大家介绍了如何爬取在 BigOne 上线的数字资产的交易数据. 其次,通过图文 如何利用BigOne的API制作自动化交易系统 – ...
- css网格_快活的Gridmas! 使用CSS网格构建喜庆的日历
css网格 在本教程中,我们将使用CSS Grid,SVG和一些节日的欢呼声来构建季节性出现日历! 让我们先看一下我们将要朝着什么方向前进-单击日期以查看其背后的内容: 您需要什么 本教程实际上并不需 ...
- Turing渲染着色器网格技术分析
Turing渲染着色器网格技术分析 图灵体系结构通过使用 网格着色器 引入了一种新的可编程几何着色管道.新的着色器将计算编程模型引入到图形管道中,因为协同使用线程在芯片上直接生成紧凑网格( meshl ...
- 2022-2028年中国塑料网格板行业市场行情动态及发展趋向分析报告
[报告类型]产业研究 [出版时间]即时更新(交付时间约3个工作日) [发布机构]智研瞻产业研究院 [报告格式]PDF版 本报告介绍了塑料网格板行业相关概述.中国塑料网格板行业运行环境.分析了中国塑料网 ...
- 用Apache Ignite实现可扩展的数据网格
在本文中,我们将先介绍数据网格(Data Grid)的基本概念.属性.以及能够提供的服务,然后讨论如何设计可扩展的数据网格,以满足实际场景的业务需求. 什么是数据网格? 数据网格是一组能够提供共享数据 ...
- Open3d学习计划—高级篇 8(网格变形)
Open3D是一个开源库,支持快速开发和处理3D数据.Open3D在c++和Python中公开了一组精心选择的数据结构和算法.后端是高度优化的,并且是为并行化而设置的. 本系列学习计划有Blue同学作 ...
最新文章
- Java除法不精确引入BigDecimal
- IntelliJ IDEA 2020.1 EAP2 发布:新增禅模式和 LightEdit 模式
- 网站优化之如何辨别关键词的相关性?
- Linux 防火墙工具--iptables
- 使用RequestHandlerRetryAdvice重试Web服务操作
- 图像分割-LOG检测器和DOG检测器
- 切记!职场邮件需注意的细节
- BT5 R1不能启动ibus输入法解决方案
- zookeeper无法启动的原因定位
- 2. 字符串、向量和数组
- 软件产品测试报告模板
- 安卓psp模拟器哪个好_psp模拟器安卓完美版下载_psp模拟器完美版手机版下载_玩游戏网...
- 东芝抢先一步,推出了全球首款16TB容量的硬盘MG08系列
- web安全---XSS的形成原理
- 使用canvas压缩图片
- Akka and Actors
- Remo Repair PowerPoint(PPT修复工具)v2.0官方版
- 统考计算机三次没过怎么办,网络教育统考一直没过怎么办
- DNS原理与搭建(一)
- UE4移动平台AR开发快速预览