高维网络

【题目描述】 
现在有一个 d 维的坐标网格,其中第 i 维坐标的范围是[0,a_i]。在这个范围内建立一个有向图:我们把范围内的每个整点(每一维坐标均为整数的点)当做图上的顶点。设点 A(0,0,⋯,0),B(a_1,a_2,⋯,a_d)。对于范围内的点(x_1,x_2,⋯,x_d),它会向以下这些点(如果目标点在范围内)连有向边:(x_1+1,x_2,⋯,x_d),(x_1,x_2+1,⋯,x_d),⋯,(x_1,x_2,⋯,x_d+1) 
现在从点 A 到点 B 会有若干条路径,路径的条数可以十分简单地算出。然而不幸的是,范围内有 p 个点被破坏了(点 A 和点 B 不会被破坏) ,其中第 i个点的坐标为(x_(i,1),x_(i,2),⋯,x_(i,d))。你需要算出从点 A 到点B 剩余的路径条数。 
由于答案可能很大,你只需要输出它对 1,000,000,007 取模的结果。 
【输入格式】 
第一行为两个整数 d,p。 
第二行为 d 个整数,其中第 i 个数是 a_i。 
接下来 p 行,每行 d 个整数,其中第 i 行第 j 个数是 x_(i,j)。 
【输出格式】 
一个整数,表示从点 A 到点 B 剩余的路径条数对 1,000,000,007 取模的结果。 
【输入样例】 
2 1 
2 1 
1 0 
【输出样例】 

【数据范围】 

30分算法
• 在前30分当中,数据规模非常小,可以暴搜每条路线。

d=1的算法
• 对于d=1的情况,如果没有点被破坏则答案是1,否则答案是0。

p=0的算法

•运用排列组合公式:二维:C(n,n+m);

多维:

阶乘可以暴力算,注意除法要用逆元(费马小定理求逆元)算。

【题解】【dp+组合数+容斥原理】 
【f[i]表示从A到i不经过被破坏的点的路径条数;g[i][j]表示从i到j可以经过的被破坏的点的方案数(可以用组合数求)】 
【g[i][j]:(各维度权值之和的阶乘)/(各维度阶乘之积),如二维情况:(行数+列数)!/(行数!×列数!)】 
【f[i]=总路径条数-不合法,f[x]=g[A][x]-Σf[y]*g[y][x]】 
【最后输出f[B]】

 #include<iostream>
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#define man 10000010
#define sc(x) scanf("%d",&x)
#define ll long long
#define mod 1000000007
using namespace std;
struct node
{
int x[];
}a[];//每个点的坐标
ll mi[man],sum[],f[],g[][],h[];
/*
mi[]:求i的阶乘;
sum[]:每个点的坐标和(为了之后的p=0做准备);
f[]:从A到i不经过被破坏的点的路径条数;
g[][]:从i到j可以经过的被破坏的点的方案数(可以用组合数求);
h[]:每两个点坐标之间的差值;
*/
int d,p;
int cmp(node a,node b)
{
for(int i=;i<=d;i++)
{
if(a.x[i]<b.x[i])return ;
if(a.x[i]>b.x[i])return ;
}
}
// cmp:从一维开始从小到大排序;
inline void pow1()
{ mi[]=;
for(ll i=;i<=;i++)
mi[i]=(mi[i-]*i)%mod;
}
//pow1:计算阶乘;
ll bpow(int a,int b)
{
ll ans=,base=a;
while(b)
{
if(b&) ans=ans*base%mod;
base=base*base%mod;
b>>=;
}
return ans;
}
//快速幂;
inline void solve()
{
for(int i=;i<=p;i++)
{
ll t=mi[sum[i]];
ll t1=;
for(int j=;j<=d;j++)
if(a[i].x[j])
t1=(t1*mi[a[i].x[j]])%mod;
ll ans=bpow(t1,mod-);
g[][i]=t*ans%mod;
}//运用费马小定理计算从A点至各点的路径总数;
for(int i=;i<=p;i++)
for(int j=;j<=p;j++)
{
ll tot=;bool b=;
for(int k=;k<=d;k++)
{
h[k]=a[j].x[k]-a[i].x[k];
tot+=h[k];
if(h[k]<) //因为是单向边(从i至j),所以j-i的坐标差>=0;
{
b=;
break;
}
}
if(!b) continue;
ll t=mi[tot];
ll t1=;
for(int k=;k<=d;k++)
if(h[k]) t1=(t1*mi[h[k]])%mod;
ll ans=bpow(t1,mod-);
g[i][j]=t*ans%mod;
}//运用费马小定理求两点之间路径总数;
return ;
} int main()
{ freopen("cube.in","r",stdin);
freopen("cube.out","w",stdout);
sc(d);sc(p);
p++;
for(int i=;i<=d;i++)
sc(a[p].x[i]);//每维极值相当于B点(终点)坐标;
for(int i=;i<=p-;i++)
for(int j=;j<=d;j++)
sc(a[i].x[j]);
sort(a+,a++p,cmp);
for(int i=;i<=p;i++)
for(int j=;j<=d;j++)
{sum[i]+=a[i].x[j];sum[i]%=mod;}
pow1();
solve();//预处理g[i][j];
for(int i=;i<=p;i++)
{
f[i]=g[][i]%mod;
for(int j=;j<i;j++)
f[i]=(f[i]-f[j]*g[j][i])%mod;
f[i]=(f[i]%mod+mod)%mod;
}
cout<<f[p]<<endl;
return ;
}

费马小定理:a/b mod p ==a* b^p-2 mod p;

证明略。

STREAMING #5 题解 3.高位网络的更多相关文章

  1. 【简】题解 P4297 [NOI2006]网络收费

    传送门:P4297 [NOI2006]网络收费 题目大意: 给定一棵满二叉树,每个叶节点有一个状态(0,1),任选两个叶节点,如果这两个叶节点状态相同但他们的LCA所管辖的子树中的与他们状态相同的叶节 ...

  2. 【题解】HNOI2016网络

    整体二分是个好东西!可我忘记了它QAQ其实当你知道这题可以整体二分的时候就已经不难了(个人觉得这是最难想到的一点啊).整体二分的话,我们就可以把问题转化为是否有一条权值 \(>= k\) 的链经 ...

  3. CCF-CSP题解 201403-4 无线网络

    新建不超过\(k\)个无线路由器,求使路由器1.2连通最少的中间路由器. 首先常规建图,将相距不超过\(r\)的路由器(包括新建的)相连. 想到了分层\(dijkstra\).类似的,作\(bfs\) ...

  4. CCF-CSP题解 201709-4 通信网络

    dfs #include <bits/stdc++.h> const int maxn = 1000; const int maxm = 10000; using namespace st ...

  5. 【题解】2021CSP-J2T3网络连接

    目录 题目链接 题目分析 是否重复 读入提取数 非法情况判断 参考代码 题目链接 题目分析 map不会冲突!!不一定要like代码中那样加-号! 模拟,算不上大, 首先,我们想想整个流程: 现在,我们 ...

  6. 网络-01-端口号-linux端口详解大全

    0 | 无效端口,通常用于分析操作系统1 | 传输控制协议端口服务多路开关选择器2 | 管理实用程序3 | 压缩进程5 | 远程作业登录7 | 回显9 | 丢弃11 | 在线用户13 | 时间17 | ...

  7. noip做题记录+挑战一句话题解?

    因为灵巧实在太弱辽不得不做点noip续下命QQAQQQ 2018 积木大赛/铺设道路 傻逼原题? 然后傻逼的我居然检查了半天是不是有陷阱最后花了差不多一个小时才做掉我做过的原题...真的傻逼了我:( ...

  8. CCF-CSP认证 C++题解目录

    持续更新中,记录刷题过程并分享一下小小的心得总结. 试题编号 试题名称 标签 202006-1 线性分类器 | 题解 线性规划 202006-2 稀疏向量| 题解 归并排序思想 202006-3 化学 ...

  9. [BZOJ2072][POI2004] MOS过桥

    Description 一个夜晚一些旅行者想要过桥. 他们只有一个火把. 火把的亮光最多允许两个旅行者同时过桥. 没有火把或者多于2个人则不能过桥.每个旅行者过桥都需要特定的时间, 两个旅行者同时过桥 ...

随机推荐

  1. 数组与指针的区别,以及在STL中传递数组/指针

    数组和指针在作为实参传入T[] 或T*的形参时没有区别 void f(int pi[]) { cout << sizeof(pi) << endl; } int a[5] = ...

  2. android之ffmpeg:设置cygwin

    开发android ndk 的时候需要一个编译工具编译c程序,ndk需要linux下编译,所以win环境下提供Cygwin模拟linux编译C android-ndk 较低版本的这个工具的配置网上很多 ...

  3. Spring AOP两种实现方式

    一. AOP 概念: Spring AOP 即Aspect Oriented Programming(面向切面编程), 实现方式分为两种: 1. 注解(Annotation) 2. 配置(Config ...

  4. java代码--------随机输出100个随机数,要求每行10个数

    总结:不敢爱你么开口 package com.sads; ///实现随机输出100个数字,数字是0到9之间,每行输出10个 public class Wss { public static void ...

  5. 协议栈CheckList

    协议?何谓协议?协议是用来干什么的? 与人类活动进行对比即可理解协议,因为我们无时无刻不在执行协议! 举一个典型交互过程: 人类协议(至少说是好的行为方式)要求一方首先进行问候(张三对李四“你好”), ...

  6. ThinkPHP Http工具类(用于远程采集 远程下载) phpSimpleHtmlDom采集类库_Jquery筛选方式 使用phpQuery轻松采集网页内容http://www.thinkphp.cn/extend/541.html

    [php]代码库 view sourceprint? <?php // +------------------------------------------------------------ ...

  7. sqlldr并发

    sage: SQLLDR keyword=value [,keyword=value,...]   部分关键字:     userid -- ORACLE username/password    c ...

  8. CocoStudio创建动画帧

    进入动画编辑器 选择“形体模式” 右键点击资源窗口的资源,可以进行删除,重命名的操作:  可以再资源窗口下方的预览窗口,查看选中的资源预览效果图: 右键点击“对象结构”,创建图层 选择“动画模式” 右 ...

  9. 转:Numpy教程

    因为用到theano写函数的时候饱受数据结构困扰 于是上网找了一篇numpy教程(theano的数据类型是基于numpy的) 原文排版更好,阅读体验更佳: http://phddreamer.blog ...

  10. C++函数及参数

    传值->传递的是数据副本(结构.普通数据类型数据) 传地址->传递的是数据变量的地址(数组等) 传值的缺点是需要复制数据副本,数据量大可能增加内存需求,降低系统运行速度; 传地址也有传地址 ...