#排列组合#CF1550D Excellent Arrays
分析
对于excellent的 \(a\) 来说 \(|a_i-i|=x\) 的值是固定的,考虑枚举它
一半正一半负时函数值是最大的,当 \(n\) 为奇数时要分为两种情况(不过可以通过杨辉三角合并)
问题是,由于 \(l,r\) 的范围,并不能做到所有位置都能可正可负,不过不超过 \(mn=\min\{1-l,r-n\}\) 时是可以的,也就是 \(C(n,mid)*mn\)。
之后应分为两个阶段,绝对值增加1会产生1个不能可正可负,不超过 \(mx=\max\{1-l,r-n\}\) 时,枚举 \(i(mn+i=x)\) 即为 \(C(n-i,mid-i)\)
或者产生2个不能可正可负,此时在上一阶段的上界基础上继续增加,就是 \(C(n-i*2-(mx-mn),mid-i-(mx-mn))\)
注意 \(i\) 在第一阶段超过 \(mid\) 抑或是第二阶段超过 \(mid-(mx-mn)\) 时已经无法产生贡献,此时可直接终止,那么复杂度就是 \(O(n)\) 的
代码(里面的 \(mx\) 已经减去了 \(mn\))
#include <cstdio>
#include <cctype>
#include <algorithm>
using namespace std;
const int N=200011,mod=1000000007;
int inv[N],fac[N],n,L,R,mn,mx,mid,odd,ans;
int iut(){
int ans=0,f=1; char c=getchar();
while (!isdigit(c)) f=(c=='-')?-f:f,c=getchar();
while (isdigit(c)) ans=ans*10+c-48,c=getchar();
return ans*f;
}
void print(int ans){
if (ans>9) print(ans/10);
putchar(ans%10+48);
}
void Mo(int &x,int y){x=x+y>=mod?x+y-mod:x+y;}
int C(int n,int m){return 1ll*fac[n]*inv[m]%mod*inv[n-m]%mod;}
int main(){
fac[0]=inv[0]=fac[1]=inv[1]=1;
for (int i=2;i<N;++i) inv[i]=1ll*(mod-mod/i)*inv[mod%i]%mod;
for (int i=2;i<N;++i) fac[i]=1ll*fac[i-1]*i%mod,inv[i]=1ll*inv[i-1]*inv[i]%mod;
for (int T=iut();T;--T,putchar(10)){
n=iut(),L=iut(),R=iut(),mid=(n+1)>>1;
mn=min(1-L,R-n),mx=max(1-L,R-n)-mn;
odd=n&1,ans=1ll*mn*C(n+odd,mid)%mod;
for (int i=1;i<=mx&&i<=mid;++i) Mo(ans,C(n-i+odd,mid-i));
for (int i=1;i<=mid-mx&&i*2+mx<=n;++i) Mo(ans,C(n-i*2-mx+odd,mid-mx-i));
print(ans);
}
return 0;
}
#排列组合#CF1550D Excellent Arrays的更多相关文章
- CF1550D Excellent Arrays
考虑每个数一定是这个形式: \(i + x,i - x\) 所以如果我们要构造一个最大的数组. 那一定是这样的形式: 有一半为\(i + x\),有一半\(i - x\) 那么我们发现每个数有这样一个 ...
- java-算法-排列组合
package com.qinghuainvest.utils.algorithm; import java.util.ArrayList; import java.util.Arrays; impo ...
- 数组排列组合问题——BACKTRACKING
BACKTRACKING backtracking(回溯法)是一类递归算法,通常用于解决某类问题:要求找出答案空间中符合某种特定要求的答案,比如eight queens puzzle(将国际象棋的八个 ...
- 给定数组a[1,2,3],用a里面的元素来生成一个长度为5的数组,打印出其排列组合
给定数组a[1,2,3],用a里面的元素来生成一个长度为5的数组,打印出其排列组合 ruby代码: def all_possible_arr arr, length = 5 ret = [] leng ...
- JavaScript 二维数组排列组合2
<html> <head> <title>二维数组排列组合</title> </head> <body> <div id= ...
- JavaScript 递归法排列组合二维数组2
<html> <head> <title>二维数组排列组合</title> </head> <body> <div id= ...
- JavaScript 递归法排列组合二维数组
<html> <head> <title>二维数组排列组合</title> </head> <body> <div id= ...
- JavaScript 二维数组排列组合
<html> <head> <title>二维数组排列组合</title> </head> <body> <div id= ...
- 学习sql中的排列组合,在园子里搜着看于是。。。
学习sql中的排列组合,在园子里搜着看,看到篇文章,于是自己(新手)用了最最原始的sql去写出来: --需求----B, C, F, M and S住在一座房子的不同楼层.--B 不住顶层.C 不住底 ...
- .NET平台开源项目速览(11)KwCombinatorics排列组合使用案例(1)
今年上半年,我在KwCombinatorics系列文章中,重点介绍了KwCombinatorics组件的使用情况,其实这个组件我5年前就开始用了,非常方便,麻雀虽小五脏俱全.所以一直非常喜欢,才写了几 ...
随机推荐
- Jenkins流水线使用@Grab 导入Maven库
有个需求需要在pipeline中调用Java的SDK去执行业务 使用 @Grab 注解可以在Maven中导入Java 库, @Grab('org.apache.commons:commons-math ...
- sort.interface接口
一个内置的排序算法需要知道三个东西:序列的长度,表示两个元素比较的结果,一种交换两个元素的方式:这就是sort.Interface的三个方法: package sort type Interface ...
- Google Chrome 开启多下载下载,提高文件下载速度
在地址栏输入: chrome://flags/#enable-parallel-downloading Parallel downloading改为Enabled后重启浏览器即可打开多线程下载 (多线 ...
- PMP考试之【PMBOK(第六版)49个过程及ITTO】
- 【Azure 环境】台湾同胞:詢問大陸所有廠牌手機是否都可透過通知中心發送訊息
什么是 Azure 通知中心? Azure 通知中心提供易于使用且向外扩展的推送引擎,可用于将通知发送到任何平台 (iOS.Android.Windows.Kindle.百度等 ) 从任何后端 (云和 ...
- C#多线程(8):线程完成数
目录 解决一个问题 CountdownEvent 类 构造函数和方法 示例 解决一个问题 假如,程序需要向一个 Web 发送 5 次请求,受网路波动影响,有一定几率请求失败.如果失败了,就需要重试. ...
- 线段树-多个懒标记pushdown
P3373 [模板]线段树 2 这里需要用到两个懒标记,一个懒标记为add,记录加,另一个懒标记为mul,记录乘. 我们需要规定一个优先级,然后考虑如何将懒标记下传. 这里无非有两种顺序,一种是先乘后 ...
- vite环境配置mockjs
mockjs使用文档v2.9.6 安装插件 npm i mockjs -S npm i vite-plugin-mock@2.9.6 配置vite.config.ts文件 export default ...
- dangle = dance + toggle - dan 向上跳 gle 摆动
dangle = dance + toggle - dan 向上跳 gle 摆动 dangle 英 [ˈdæŋɡl] 美 [ˈdæŋɡl] v.悬垂;悬挂;悬荡;悬摆;提着(某物,任其自然下垂或摆动) ...
- idea dev 分支合并到 master 流程
合并分支前要全部提交 包括config.js 要不merge时候很麻烦 1 切换到master分支 Checkout 2 Merge into Current 3 commit push 4 切换回d ...