数论三之排列组合Ⅱ——Virus Tree 2,RGB Coloring,123 Triangle,排列计数,排队,卡农

丝且人一口

  • Virus Tree 2
    • description
    • solution
    • code
  • RGB Coloring
    • description
    • solution
    • code
  • 123 Triangle
    • description
    • solution
    • code
  • [SDOI2016]排列计数
    • description
    • solution
    • code
  • [HNOI2012]排队
    • description
    • solution
    • code
  • [HNOI2011]卡农
    • description
    • solution
    • code

Virus Tree 2

description

solution

距离不超过222的点,可能是儿子/孙子/父亲/爷爷

考虑从上到下,由上面的颜色选取决定下面的颜色

显然,第一个点有KKK种选择,第二个点有K−1K-1K1种,每次不同都要−1-11

答案就是每个点的选择的乘积

所以只需要把这种过程的递减通过dfs树来实现

对于现在的子树根节点uuu,如果vvv是第一个儿子,那么需要考虑vvv有没有爷爷

如果不是第一个儿子,那么就是前一个儿子的方案数再−1-11

code

#include <cstdio>
#include <vector>
using namespace std;
#define mod 1000000007
#define int long long
#define maxn 1000005
vector < int > G[maxn];
int n, k;
int w[maxn];void dfs( int u, int fa ) {int r = 0;for( auto v : G[u] ) {if( v == fa ) continue;else {if( r ) w[v] = r - 1;else if( ! fa ) w[v] = k - 1;else w[v] = k - 2;r = w[v]; }}for( auto v : G[u] ) if( v ^ fa ) dfs( v, u );
}signed main() {scanf( "%lld %lld", &n, &k );for( int i = 1, u, v;i < n;i ++ ) {scanf( "%lld %lld", &u, &v );G[u].push_back( v );G[v].push_back( u );}w[1] = k;dfs( 1, 0 );int ans = 1;for( int i = 1;i <= n;i ++ )if( w[i] <= 0 ) return ! printf( "0\n" );else ans = ans * w[i] % mod;printf( "%lld\n", ans );return 0;
}

RGB Coloring

description

solution

将绿色A+BA+BA+B看成既涂了红色AAA,又涂了蓝色BBB,则红色和蓝色格子彼此独立,就算涂在同一个格子上也没关系

枚举红色格子的数量iii,计算得出蓝色格子数量j=K−A×iBj=\frac{K-A\times i}{B}j=BKA×i

判断格子数量为整数且都在nnn以内即可,然后用组合计数从nnn个格子中选红/蓝色

∑Cni×Cnj\sum C_n^i\times C_n^jCni×Cnj

code

#include <cstdio>
#define int long long
#define mod 998244353
#define maxn 300005
int n, A, B, k;
int fac[maxn], inv[maxn];int qkpow( int x, int y ) {int ans = 1;while( y ) {if( y & 1 ) ans = ans * x % mod;x = x * x % mod;y >>= 1;}return ans;
}void init() {fac[0] = inv[0] = 1;for( int i = 1;i <= n;i ++ )fac[i] = fac[i - 1] * i % mod;inv[n] = qkpow( fac[n], mod - 2 );for( int i = n - 1;i;i -- )inv[i] = inv[i + 1] * ( i + 1 ) % mod;
}int C( int n, int m ) {if( m < 0 || n < m ) return 0;else return fac[n] * inv[m] % mod * inv[n - m] % mod;
}signed main() {scanf( "%lld %lld %lld %lld", &n, &A, &B, &k );init();int ans = 0; for( int i = 0, j;i <= n;i ++ ) {if( ( k - A * i ) % B ) continue;else j = ( k - A * i ) / B;ans = ( ans + C( n, i ) * C( n, j ) ) % mod;}printf( "%lld\n", ans );return 0;
}

123 Triangle

description

solution

N>1N>1N>1式子是差分形式,后面序列只有能是0/1/20/1/20/1/2

(除非N=1N=1N=1的情况答案有可能是333

如果此时序列有111,那么答案一定只能是0/10/10/1,因为0/20/20/2碰到111都会变成111

如果序列没有111,则答案只会是0/20/20/2,对于这种情况,将每个数/2/2/2得到结果后再×2\times 2×2是等价的

所以现在的答案都只会是0/10/10/1,考虑在(mod2)\pmod 2(mod2)意义下做

(mod2)\pmod 2(mod2)的情况下,加减法可以看成二进制的异或

所求即为一段序列相邻两个数异或直到最后成一个数的答案

考虑每个数被异或的次数,这其实是个倒杨辉三角(0,0)(0,0)(0,0)开始

长为nnn的序列的第iii个元素被异或的次数为Cn−1i−1C_{n-1}^{i-1}Cn1i1

计算在模222意义下(除法不一定有逆元)的组合数

  • 计算每个阶乘中分解222的次数,将除法变成减法,对于组合数最后剩下的222的次数为000,则为1(mod2)1\pmod 21(mod2),反之0(mod2)0\pmod 20(mod2)
  • 阶乘的分解,拆分成对每个数求出分解中222的次数,做前缀和

code

#include <cmath>
#include <cstdio>
#define maxn 1000005
int n;
char s[maxn];
int x[maxn], cnt[maxn]; int main() {scanf( "%d %s", &n, s + 1 );n --;for( int i = 1;i <= n;i ++ )x[i] = fabs( s[i] - s[i + 1] );bool flag = 1;for( int i = 1;i <= n;i ++ )if( x[i] == 1 ) { flag = 0; break; }if( flag ) for( int i = 1;i <= n;i ++ )x[i] >>= 1;for( int i = 1;i <= n;i ++ ) {int t = i;while( ! ( t & 1 ) ) t >>= 1, cnt[i] ++;cnt[i] += cnt[i - 1];}int ans = 0;for( int i = 1;i <= n;i ++ )ans ^= cnt[n - 1] - cnt[i - 1] - cnt[n - i] ? 0 : ( x[i] & 1 );if( flag ) ans <<= 1;printf( "%d", ans );return 0;
} 

[SDOI2016]排列计数

description

solution

组合数从nnn个中选mmm个强制ai=ia_i=iai=i,剩下的n−mn-mnmai≠ia_i≠iai=i,就是n−mn-mnm的错排数

code

#include <cstdio>
#define mod 1000000007
#define int long long
#define maxn 1000005
int fac[maxn], inv[maxn], D[maxn];
int T, n, m;int qkpow( int x, int y ) {int ans = 1;while( y ) {if( y & 1 ) ans = ans * x % mod;x = x * x % mod;y >>= 1;}return ans;
}void init() {fac[0] = inv[0] = 1;for( int i = 1;i < maxn;i ++ )fac[i] = fac[i - 1] * i % mod;inv[maxn - 1] = qkpow( fac[maxn - 1], mod - 2 );for( int i = maxn - 2;i;i -- )inv[i] = inv[i + 1] * ( i + 1 ) % mod;D[0] = 0, D[1] = 0, D[2] = 1;for( int i = 3;i < maxn;i ++ )D[i] = ( D[i - 1] + D[i - 2] ) * ( i - 1 ) % mod;
}int C( int n, int m ) {return fac[n] * inv[m] % mod * inv[n - m] % mod;
}signed main() {init();scanf( "%lld", &T );while( T -- ) {scanf( "%lld %lld", &n, &m );if( n == m ) printf( "1\n" ); else printf( "%lld\n", C( n, m ) * D[n - m] % mod );}return 0;
}

[HNOI2012]排队

description

solution

不给模数还明示答案可能很大,赤裸裸的大整数胁迫!!居心叵测!!

两名老师真的是很烦了,没有这么讨人厌的老师,可以直接女生插板法了

  • 两名老师之间是男生

    先排男生AnnA_n^nAnn,产生n+1n+1n+1个空

    再插板两名老师,An+12A_{n+1}^2An+12,产生n+3n+3n+3个空

    最后插板mmm名女生,An+3mA_{n+3}^mAn+3m

  • 两名老师之间是女生

    先排男生AnnA_n^nAnn

    再打包两名老师放同一个隔板里,老师间还有顺序,A22Cn+11A_2^2C_{n+1}^1A22Cn+11

    先强制选一名女生放进老师中间mmm,剩下的就隔板插

    男生nnn个,老师和强制女生打包装成一个,总共是n+1n+1n+1个,产生n+2n+2n+2个空,An+2m−1A_{n+2}^{m-1}An+2m1

综上,ans=AnnAn+12An+3m+A22Cn+11An+2m−1ans=A_n^nA_{n+1}^2A_{n+3}^m+A_2^2C_{n+1}^1A_{n+2}^{m-1}ans=AnnAn+12An+3m+A22Cn+11An+2m1

同样,老师不相邻===不考虑老师−-老师相邻

  • 不考虑老师

    把老师当成男的,女的直接插,An+2n+2An+3mA_{n+2}^{n+2}A_{n+3}^mAn+2n+2An+3m

  • 老师相邻

    捆绑法强制两名老师一起当成一个男的A22An+1n+1An+2mA_2^2A_{n+1}^{n+1}A_{n+2}^mA22An+1n+1An+2m

二者做差就是答案
在这里插入图片描述

code

#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;
int n, m;struct Int {int g[20000], len;Int() {memset( g, 0, sizeof( g ) );len = 0;}Int( int x ) {memset( g, 0, sizeof( g ) );len = 0;if( ! x ) len = 1;else while( x ) g[len ++] = x % 10, x /= 10;}void clean() {while( len > 1 && ! g[len - 1] ) len --;}Int operator - ( Int t ) {Int ans;ans.len = len;for( int i = 0;i < t.len;i ++ ) {ans.g[i] = g[i] - t.g[i];if( ans.g[i] < 0 ) ans.g[i] += 10, g[i + 1] --;}for( int i = t.len;i < len;i ++ )ans.g[i] = g[i]; ans.clean();return ans;}Int operator * ( Int t ) {Int ans;ans.len = len + t.len;for( int i = 0;i < len;i ++ )for( int j = 0;j < t.len;j ++ )ans.g[i + j] += g[i] * t.g[j];for( int i = 0;i < ans.len;i ++ )ans.g[i + 1] += ans.g[i] / 10, ans.g[i] %= 10;ans.len ++;ans.clean();return ans;} void print() {for( int i = len - 1;~ i;i -- )printf( "%d", g[i] );}};Int calc( int n, int m ) {Int ans = ( 1 );for( int i = n - m + 1;i <= n;i ++ )ans = ans * i;return ans;
}int main() {scanf( "%d %d", &n, &m );Int ans;ans = calc( n + 2, n + 2 ) * calc( n + 3, m ) - calc( 2, 2 ) * calc( n + 1, n + 1 ) * calc( n + 2, m );	ans.print();return 0;
}

[HNOI2011]卡农

description

solution

同种音乐其实通过除以m!m!m!就可以消掉

相当于在SSS中选mmm个子集,满足

  • 子集非空
  • 不存在两个完全一样的子集
  • ∀i,i∈[1,n]\forall_{i,i\in[1,n]}i,i[1,n]每个元素出现次数为偶数

fi:f_i:fi: 考虑iii个子集,满足以上所有性质的方案数

  • 如果知道i−1i-1i1个子集的,那么iii个子集的集合就被确定了下来A2n−1i−1A_{2^n-1}^{i-1}A2n1i1
  • 如果子集是空,那么去掉这个子集剩下的i−1i-1i1个子集是合法方案fi−1f_{i-1}fi1
  • 如果iii子集与jjj子集重复,jjji−1i-1i1种选择,剔除这两个子集剩下i−2i-2i2子集是合法的fi−2f_{i-2}fi2iii子集选择有2n−1−(i−2)2^n-1-(i-2)2n1(i2)(排除掉剩下i−2i-2i2个子集,不能与之重复)

在这里插入图片描述

最后别忘了m!m!m!

code

#include <cstdio>
#define mod 100000007
#define int long long
#define maxn 1000005
int n, m;
int A[maxn], f[maxn];int qkpow( int x, int y ) {int ans = 1;while( y ) {if( y & 1 ) ans = ans * x % mod;x = x * x % mod;y >>= 1;}return ans;
}signed main() {scanf( "%lld %lld", &n, &m );f[0] = 1, f[1] = 0;int t = ( qkpow( 2, n ) - 1 + mod ) % mod;A[0] = 1;for( int i = 1;i <= m;i ++ )A[i] = ( A[i - 1] * ( t - i + 1 ) % mod + mod ) % mod;int MS = 1;for( int i = 2;i <= m;i ++ ) {f[i] = ( A[i - 1] - f[i - 1] - f[i - 2] * ( i - 1 ) % mod * ( t - i + 2 ) % mod ) % mod;MS = MS * i % mod;}printf( "%lld\n", ( f[m] + mod ) % mod * qkpow( MS, mod - 2 ) % mod );return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/317309.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

.NET Core开发日志——OData

简述OData&#xff0c;即Open Data Protocol&#xff0c;是由微软在2007年推出的一款开放协议&#xff0c;旨在通过简单、标准的方式创建和使用查询式及交互式RESTful API。类库在.NET Core中想要使用OData功能的话需要添加Microsoft.AspNetCore.OData包。dotnet add package M…

ML.NET 0.10特性简介

IDataView被单独作为一个类库包IDataView组件为表格式数据提供了非常高效的处理方式&#xff0c;尤其是用于机器学习和高级分析应用。它被设计为可以高效地处理高维数据和大型数据集。并且也适合处理属于更大的分布式数据集中的单个数据区块结点。在ML.NET 0.10中&#xff0c;I…

数论五之容斥——硬币购物,Gerald and Giant Chess,幸运数字,Sky Full of Stars,已经没有什么好害怕的了

容斥的神[HAOI2008]硬币购物problemsolutioncodeCF559C Gerald and Giant Chessproblemsolutioncode[SCOI2010]幸运数字problemsolutioncodeCF997C Sky Full of Starsproblemsolutioncode已经没有什么好害怕的了problemsolutioncode[JLOI2015]骗我呢problemsolutioncode容斥要么…

NET Core微服务之路:基于Ocelot的API网关Relay实现--RPC篇

前言我们都知道&#xff0c;API网关是工作在应用层上网关程序&#xff0c;为何要这样设计呢&#xff0c;而不是将网关程序直接工作在传输层、或者网络层等等更底层的环境呢&#xff1f;让我们先来简单的了解一下TCP/IP的五层模型。&#xff08;图片出自http://www.cnblogs.com/…

Windows 10《描图》应用现已开源

点击上方蓝字关注“汪宇杰博客”《描图》是我最早的Windows 10应用&#xff0c;发布至今已3年多&#xff0c;积累了全球数百万用户&#xff0c;广受好评。现已开源。这款应用为不少小朋友带去了欢乐&#xff0c;体验绘画的乐趣&#xff0c;也帮助过专业用户复刻数百幅古代绘画。…

数论六之计算几何干货——计算几何模板解释全集 及 模板检验训练场

文章目录点和向量及运算直线和线段求解点到直线的距离/点在直线上求解点到线段的距离/点在线段上求解两条线段是否相交求解两直线的交点多边形求解多边形面积求解多边形重心求解判断定点与多边形的位置关系凸包graham扫描法graham扫描法加强版圆求解圆与直线的交点求解圆与圆的…

P3959 [NOIP2017 提高组] 宝藏

P3959 [NOIP2017 提高组] 宝藏 题意: 额题意不好说&#xff0c;就是n个点m个边&#xff0c;选定一个点为根节点&#xff0c;构造一个最小生成树&#xff0c;边的权值为该该边起点到根节点之间的点的数量K&#xff08;不含根节点&#xff09; * 道路长度 1<n<12 0<m&…

如何在ASP.NET Core程序启动时运行异步任务(3)

原文&#xff1a;Running async tasks on app startup in ASP.NET Core (Part 3)作者&#xff1a;Andrew Lock译者&#xff1a;Lamond Lu之前我写了两篇有关在ASP.NET Core中运行异步任务的博文&#xff0c;本篇博文是对之前两篇博文中演示示例和实现方法的简短跟进。你可以通过…

【NET CORE微服务一条龙应用】应用部署

简介本章主要介绍https://github.com/q315523275/FamilyBucket上微服务一条龙应用&#xff0c;在实际使用中的应用部署&#xff0c;以原始方式部署非docker部署应用主要包括&#xff1a;1、网关应用部署2、授权认证应用部署3、配置中心查询服务端应用部署4、综合管理应用部署5、…

手工修复Azure DevOps无法连接到Azure的问题

点击上方蓝字关注“汪宇杰博客”今天我在为一个从TFVC迁移到Git的老项目重新配置发布到Azure App Service的CI/CD管线的时候&#xff0c;Azure DevOps竟然爆了。这是一个微软已知的bug&#xff0c;目前还未修复&#xff0c;我来带大家看看如何手工workaround这个问题。首先&…

NC14732 锁

NC14732 锁 题意&#xff1a; n个居民&#xff0c;门上有k把锁&#xff0c;每个居民有若干钥匙&#xff0c;为1到k的一个子集&#xff0c;如果几名居民的钥匙的并集是1到k&#xff0c;即他们拥有全部锁的对应钥匙。 求最小的k&#xff0c;使得可以适当地给居民们每人若干钥匙…

.NET Core实战项目之CMS 第十七章 CMS网站系统的部署

目前我们的.NET Core实战项目之CMS系列教程基本走到尾声了&#xff0c;通过这一系列的学习你应该能够轻松应对.NET Core的日常开发了&#xff01;当然这个CMS系统的一些逻辑处理还需要优化&#xff0c;如没有引入日志组件以及缓存功能&#xff0c;权限目前只支持控制到菜单&…

如何用EFCore Lazy Loading实现Entity Split

α角 与 β角支持 现实生活 的 计算机系统&#xff0c;总有着两大偏差&#xff0c;第一个是 现实生活 与 计算机系统 的α角&#xff0c;另外一个是计算机系统的 逻辑设计 与 物理设计 的β角。举个栗子&#xff1a;α角&#xff1a;假设某个公司的商业流程&#xff0c;我们在做…

.NET Core 开源项目 Anet 在路上

今天给大家介绍我刚开源的一个 .NET Core 项目&#xff1a;Anet。Anet 的目标是实现一个 .NET Core 通用库、通用框架和通用模板。我给它的定义是&#xff1a;A .NET Core Common Lib, Framework and Boilerplate.它的取名正是来自于这句话的前面四个字母&#xff1a;ANET。Ane…

模板:后缀自动机(SAM)

所谓后缀自动机&#xff0c;就是通过后缀建立的自动机 &#xff08;逃&#xff09; 请允许我先介绍一下后缀家族&#xff1a; &#xff08;又逃&#xff09; 前言 OI生涯目前为止学习的最为难以理解的算法&#xff0c;没有之一。 到现在也没有完全的理解。 qwq 概念 定义&…

.NET 开源项目 Anet 介绍

使用 Anet 有一段时间了&#xff0c;已经在我的个人网站&#xff08;如 bookist.cc&#xff09;投入使用&#xff0c;目前没有发现什么大问题&#xff0c;所以才敢写篇文章向大家介绍。GitHub 地址&#xff1a;https://github.com/anet-team/anetAnet 是一个 .NET Core 通用框架…

我的十年创业路

记十年创业的心路历程和我的创业思辨导读1 为什么写这篇文章2 详细的总结和思辨 2.01 感恩 2.02 为什么创业 2.03 十年流水账 2.04 经历了哪些失败 2.05 重要的职场基础 2.06 持续的学习和进步 2.07 创业与兴趣 2.08 价值观的碰撞和选择 2.09 合作与…

DotNetty 实现 Modbus TCP 系列 (一) 报文类

Modbus TCP/IP 报文报文最大长度为 260 byte (ADU 7 byte MBAP Header 253 byte PDU)Length Unit Identifier 长度 PDU 长度MBAP HeaderPDUPDU 由两部分构成&#xff1a;Function Code(功能码) 和 Data 组成Function Code部分功能码&#xff1a;报文类ModbusHeaderModbusHe…

专题突破三之并查集Ⅰ——Portal,parity,食物链,程序自动分析,Almost Union-Find,洞穴勘测

文章目录Portalparity[NOI2001] 食物链程序自动分析UVA11987 Almost Union-Find[SDOI2008] 洞穴勘测Portal source 百度翻译简直就是个鬼…(((m -__-)m 离线 将边和询问按权值排序&#xff0c;指针&#xff0c;将所有权值不超过当前询问iii的边全加进去 答案路径自然是不连…

C# 未来新特性:静态委托和函数指针

C# 每发布一次新版本&#xff0c;都会增加一些底层相关的新特性&#xff0c; 这些特性对大多数商业程序来说并没什么实际用处&#xff0c;主要用于那些对性能有很高要求的代码&#xff0c;如图形处理、机器学习以及数学工具包&#xff0c;等等。接下来的两个提案&#xff0c;主…