首页 > 其他分享 >P9018 [USACO23JAN] Moo Route G 题解

P9018 [USACO23JAN] Moo Route G 题解

时间:2024-01-17 09:22:49浏览次数:19  
标签:invfac int 题解 Route USACO23JAN MAXN ans fac mod

首先有一些性质。因为保证有解,所以 \(a_i\) 一定都是 \(2\) 的倍数(必须一来一回)。并且总的步数应该为 \(\sum a_i\)。

先考虑 \(n \le 2\) 的情况,这时我们可以分情况讨论。因为每一条线段都会被来回走两次,所以我们可以先把每一个数都除以 \(2\)。

  1. 若 \(a =b\),则最优情况一定是形如 \(RRLLRRLL\dots\) 的,否则转向次数一定更多。

  2. 若 \(a<b\),我们假设先按上述情况的方式走完,那么右边线段应该还需要再被走 \(b-a\) 次。考虑这 \(b-a\) 次在什么时候走最优,会发现如果选择走到中间点的时候再走一次 \(RL\) 是最优的。所以我们每一次走到中间点都可以选择走一次 \(RL\)。最先总共有 \(a\) 个中间点,每走一次 \(RL\) 还会多产生一个中间点,所以总方案数是 \(\frac{\prod_{i=a}^{b-1}i}{(b-a)!}\)。

  3. 若 \(a > b\),那么左边线段应该还需要再被走 \(a-b\) 次。则会发现如果走到最左边的时候再多走一次 \(RL\) 是最优的。最先总共有 \((b+1)\) 个左边点,每一次走 \(RL\) 还会多产生一个,所以总方案数是 \(\frac{\prod_{i=(b+1)}^{a}i}{(a-b)!}\)。

现在考虑把 \(n\) 扩展到 \(10^5\)。这时我们会发现,如果我们从左往右考虑的话,那么 \(a_{i+1}\) 的选择只和 \(a_i\) 有关系,和 \(a_{i-1}\) 没有关系。所以我们可以从左往右依次将序列拆分为 \([a_1,a_2],[a_2,a_3]\) 这样长度为 \(2\) 的段,对于每一段都可以按照 \(n=2\) 的情况单独算,最终答案即为它们相乘。

#include<bits/stdc++.h>
using namespace std;
#define int long long
const int mod = 1e9 + 7; 
const int MAXN = 2e6 + 10;
int n,a,b,fac[MAXN],inv[MAXN],invfac[MAXN],p[MAXN],ans = 1;
inline int P(int l,int r){return (fac[r] * invfac[l - 1]) % mod;}
signed main()
{
	inv[0] = fac[0] = invfac[0] = 1;
	inv[1] = fac[1] = invfac[1] = 1;
	for(int i = 2;i <= 2000000;i++)
	{
		inv[i] = (inv[mod % i] * (mod - mod / i)) % mod;
		fac[i] = (fac[i - 1] * i) % mod;
		invfac[i] = (invfac[i - 1] * inv[i]) % mod;
	} 
	scanf("%lld",&n);
	for(int i = 1;i <= n;i++) scanf("%lld",&p[i]);
	for(int i = 2;i <= n;i++)
	{
		a = p[i - 1],b = p[i];
		int tmp;
		if(a % 2 == 1 || b % 2 == 1) tmp = 0;
		else if(a == b) tmp = 1;
		else if(b > a) tmp = (P(a / 2,a / 2 + (b - a) / 2 - 1) * invfac[(b - a) / 2]) % mod;
		else if(a > b) tmp = (P(b / 2 + 1,b / 2 + (a - b) / 2) * invfac[(a - b) / 2]) % mod;
		ans = (ans * tmp) % mod;
	} 
	printf("%lld",ans);
	return 0;
}

标签:invfac,int,题解,Route,USACO23JAN,MAXN,ans,fac,mod
From: https://www.cnblogs.com/Creeperl/p/17969054

相关文章

  • P9017 [USACO23JAN] Lights Off G 题解
    一次操作相当于把\(a\)异或上\(b\),修改开关的一位相当于将这一位异或上\(1\)。会发现一个很神奇的性质:初始开关对灯的影响和改变开关状态对灯的影响是独立的。而前者的影响是固定的,所以我们可以只考虑改变开关状态对灯的影响。假设一共需要\(k\)次操作能使所有灯关闭,如果我......
  • CF1876D Lexichromatography 题解
    Problem-D-CodeforcesLexichromatography-洛谷先注意读题:对于所有的值\(k\),在这个序列的任意子区间\([l,r]\)中,值为\(k\)且为红色的位置数减去值为\(k\)且为蓝色的位置数的绝对值不超过\(1\)注意是任意子区间这说明什么?说明如果只有第二个条件,我......
  • P2572 [SCOI2010] 序列操作 题解
    题解:序列操作比较综合的ds题,综合了线段树常见的几种操作:维护最大子段和、区间翻转、区间求和、区间覆盖。维护子段和常见的我们维护三类东西:前缀最长连续段、后缀最长连续段、当前区间上的最大子段和。在pushUp时,对于一个区间的前后缀最值首先等于左右子树的最长前后缀,......
  • P6054 题解
    blog。网络流——最小割。每个选手做某一套题的期望奖励固定,计算方式参考样例解释。这个假期望被去掉了。发现是典型的「\(m\)种强制选一」问题。考虑每个人都建一条链,跑最小割,每条链必定割\(\ge1\)条边,割哪条边就表示选哪套题。code,时间复杂度\(O(\text{能过})\)。......
  • 洛谷P10058 题解
    这种翻转的题明显已经做烂了好吧……首先显而易见,翻转偶数次对结果没有影响,只需要考虑奇数次翻转的情况。由于是整体移动的操作,可以抓住一个点来移动,然后还原出原来的序列。需要注意的是字符串是环形移动,因此如果当前点的位置大于字符串长度,要对字符串的长度进行取余操作。写......
  • Atcoder Beginner Contest 330 题解
    AtCoderBeginnerContest330题解A-CountingPasses签到voidShowball(){intn,l;cin>>n>>l;intcnt=0;for(inti=0;i<n;i++){intx;cin>>x;cnt+=(x>=l);}cout<<cnt<<endl;}B-Minimize......
  • route / ip route
    目录route命令格式命令功能命令参数使用示例创建静态路由iproute命令格式命令功能命令参数使用示例静态路由和动态路由静态路由动态路由适用场景routeroute命令是Linux系统中用于显示和操作IP路由表的命令。它的主要作用是创建一个静态路由,让指定的主机或网络通过一个网络接口......
  • CF1437F Emotional Fishermen 题解
    题意:有\((n\le5000)\)个渔民,每个渔民钓了一条重\(a_i\)的鱼,渔民按任意顺序展示他们的鱼。若当前渔民的鱼的重量为\(x\),之前展示过的鱼的最大重量\(y\)。一个排列满足条件当且仅当对于每个\(x\),满足\(2y\lex\)或\(2x\ley\)。问有多少个排列满足条件,对\(998244353......
  • ABC336 F Rotation Puzzle 题解
    QuestionABC336FRotationPuzzle给出一个\(H\timesW\)的矩阵,里面填有数字,有一种操作选定一个\((x,y)\)交换\((i+x,j+y)\)和\((H-i+x,W-j+y)\)对于每一个\(1\lei\leH-1,1\lej\leW-1\)问,是否能经过\(20\)次以内的操作使得,最后的矩形变成\((i,j)=((i-1)\t......
  • P1002题解
    思路设\(dp_{i,j}\)表示第\(i\)行\(j\)列卒走到这里有多少种方式。卒是可以向右和下走,所以到这个点只能从左或上来,不难得出转移公式:\(dp_{i,j}=dp_{i-1,j}+dp_{i,j-1}\)。如果马在这个点上或者说马能到这个点上,那么卒不能到这个点,也就是卒到这个点的方式为\(0\)。如......