前言

学了容斥与二项式反演,也该写写题了

题目介绍

题目网址

题意简介

现在有个人,要用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)Θ(GT​R2)大约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]网格相关推荐

  1. Loj #6060. 「2017 山东一轮集训 Day1 / SDWC2018 Day1」Set

    原题是CF上的某题,但是还要输出方案....好鬼畜啊WWW 发现答案肯定是优先 xorsum^x1 + x1 最大,然后再优先x1最小(也就是 xorsum^x1 最大). 我们把xorsum二进制分 ...

  2. 【GDKOI】2021提高Day1

    [GDKOI]2021提高Day1 2021 年广东省重点中学信息学冬令营 (GDKOI 2021) 提高组 第一试 2021 年 1 月 29 日 注意事项 严格按照题目所要求的格式进行输入.输出, ...

  3. 学习记录:UnityHDRP高清渲染管线学习 day1

    附一张这本书的封面截图 ps:(我自我介绍一下吧,高中不好好学习去了大专,现在大一暑假在一家郑州互联网公司实习,月薪4500,转正之后是八千多(我觉得挺多了),其实并不是我多聪明,只是抓住了机会不想再 ...

  4. 技术图文:如何利用BigOne的API制作自动化交易系统--网格交易法

    背景 前面,通过图文 如何利用 C# 爬取 ONE 的交易数据? 向大家介绍了如何爬取在 BigOne 上线的数字资产的交易数据. 其次,通过图文 如何利用BigOne的API制作自动化交易系统 – ...

  5. css网格_快活的Gridmas! 使用CSS网格构建喜庆的日历

    css网格 在本教程中,我们将使用CSS Grid,SVG和一些节日的欢呼声来构建季节性出现日历! 让我们先看一下我们将要朝着什么方向前进-单击日期以查看其背后的内容: 您需要什么 本教程实际上并不需 ...

  6. Turing渲染着色器网格技术分析

    Turing渲染着色器网格技术分析 图灵体系结构通过使用 网格着色器 引入了一种新的可编程几何着色管道.新的着色器将计算编程模型引入到图形管道中,因为协同使用线程在芯片上直接生成紧凑网格( meshl ...

  7. 2022-2028年中国塑料网格板行业市场行情动态及发展趋向分析报告

    [报告类型]产业研究 [出版时间]即时更新(交付时间约3个工作日) [发布机构]智研瞻产业研究院 [报告格式]PDF版 本报告介绍了塑料网格板行业相关概述.中国塑料网格板行业运行环境.分析了中国塑料网 ...

  8. 用Apache Ignite实现可扩展的数据网格

    在本文中,我们将先介绍数据网格(Data Grid)的基本概念.属性.以及能够提供的服务,然后讨论如何设计可扩展的数据网格,以满足实际场景的业务需求. 什么是数据网格? 数据网格是一组能够提供共享数据 ...

  9. Open3d学习计划—高级篇 8(网格变形)

    Open3D是一个开源库,支持快速开发和处理3D数据.Open3D在c++和Python中公开了一组精心选择的数据结构和算法.后端是高度优化的,并且是为并行化而设置的. 本系列学习计划有Blue同学作 ...

最新文章

  1. Java除法不精确引入BigDecimal
  2. IntelliJ IDEA 2020.1 EAP2 发布:新增禅模式和 LightEdit 模式
  3. 网站优化之如何辨别关键词的相关性?
  4. Linux 防火墙工具--iptables
  5. 使用RequestHandlerRetryAdvice重试Web服务操作
  6. 图像分割-LOG检测器和DOG检测器
  7. 切记!职场邮件需注意的细节
  8. BT5 R1不能启动ibus输入法解决方案
  9. zookeeper无法启动的原因定位
  10. 2. 字符串、向量和数组
  11. 软件产品测试报告模板
  12. 安卓psp模拟器哪个好_psp模拟器安卓完美版下载_psp模拟器完美版手机版下载_玩游戏网...
  13. 东芝抢先一步,推出了全球首款16TB容量的硬盘MG08系列
  14. web安全---XSS的形成原理
  15. 使用canvas压缩图片
  16. Akka and Actors
  17. Remo Repair PowerPoint(PPT修复工具)v2.0官方版
  18. 统考计算机三次没过怎么办,网络教育统考一直没过怎么办
  19. DNS原理与搭建(一)
  20. UE4移动平台AR开发快速预览

热门文章

  1. SpringMVC的请求-获得请求参数-获得POJO类型参数
  2. RocketMQ各种集群模式介绍
  3. 反射获取私有构造方法并运行
  4. 微服务发现组件Eureka:简介以及Eureka服务端开发
  5. 哨兵机制服务器环境准备
  6. c语言程序设计了解,C语言程序设计
  7. 每月分享github上有意思的项目
  8. Spring中如何使用注解来配置Bean?有哪些相关的注解?
  9. 从构建分布式秒杀系统聊聊WebSocket推送通知
  10. poj3296--Rinse(三分)