首页 > 其他分享 >计数杂题

计数杂题

时间:2024-04-17 20:11:56浏览次数:23  
标签:int ll 计数 maxn 错排 杂题 节点 dp

P4071 [SDOI2016] 排列计数 :https://www.luogu.com.cn/problem/P4071

思路:题目要求序列中m个数下标等于自身,其余n-m个数满足错排。那么每次在n个位置中选出m个 a[i]=i 的位置,之后我们再用错排公式求出n-m的错排,最后用乘法原理即可。

int f[maxn],g[maxn],d[maxn];
void init()
{
    f[0]=g[0]=1;
    d[1]=0,d[2]=1;
    for(int i=1;i<=maxn;i++)
    {
        f[i]=f[i-1]*i%mod;
        g[i]=g[i-1]*qpow(i,mod-2)%mod;
    }
    for(int i=3;i<=maxn;i++)
    {
        d[i]=(i-1)*(d[i-1]+d[i-2])%mod;//错排公式
    }
}
int C(int n,int m)
{
    return f[n]*g[m]%mod*g[n-m]%mod;
}//组合数
void solve()
{
    int n,m;
    cin>>n>>m;
    if(n==m)
    {
        cout<<1<<'\n';
        return ;
    }
    else 
    {
        cout<<C(n,m)*d[n-m]%mod<<'\n';
    }
}

P3182 [HAOI2016] 放棋子 :https://www.luogu.com.cn/problem/P3182

思路:我们可以发现题目给的要求是“每行、每列都有且仅有一个障碍”,要求放的棋子也是相同的要求。那么我们就可以把二维坐标系转化为一维。
我们准备放N个棋子,既然每行、每列都有且仅有一个障碍,那么我们可以知道转化成一维坐标系之后,对于每个即将被放置的棋子,肯定是有且仅有一个位置是不能放的。那么我们想到错排问题也是有且仅有一个位置是不能放的,就可以把这道题直接转化为错排即可。这里数据范围较大,可以直接用py。

import sys
input = sys.stdin.readline
f = [0,0,1]
n = int(input())
for i in range(3,n+1):
    f.append((i-1)*(f[i-1]+f[i-2]))
print((f[n]))

P2606 [ZJOI2010] 排列计数:https://www.luogu.com.cn/problem/P2606
思路:
首先我们会议一下关于二叉树的知识点:一个节点 u 的两个子节点的编号一定是2u和2u+1。
再回来看这道题:题目要求 p[i] > p[floor(i/2)] ,那么转变一下式子可得 p[i2] > p[i] && p[i2+1] > p[i] ,这个条件也就是说明一个节点的两个子节点比父节点大,也就是满足小根堆的性质。那么这道题我们可以先预处理出每个节点有多少子节点,最后根据小根堆的性质统计答案即可。设 dp[i] 为当前有多少个大小为i的小根堆,从深度大往深度小转移。假设当前遍历到节点 u ,该节点的左右子树共有C(s[u]-1,s[2u]) 种情况(即选择s[2u]个节点作为左子树,剩下的都为右子树),u 的两个子节点都已经在之前处理过了,直接乘法原理统计答案即可。
这题要求答案mod一个质数p,要用到Lucas定理。

#define int long long
int n,p;
#define maxn 4000011
ll qpow(ll a,ll b) {ll res=1;a%=p; assert(b>=0); for(;b;b>>=1){if(b&1)res=res*a%p;a=a*a%p;}return res;}
int f[maxn];
int dp[maxn],s[maxn];
int C(int n,int m)
{
    return f[n]*qpow(f[n-m]*f[m]%p,p-2)%p;
}
int lucas(int n,int m)
{
    if(m==0) return 1;
    return lucas(n/p,m/p)*C(n%p,m%p)%p;
}
signed main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    cin>>n>>p;
    f[0]=1;
    for(int i=1;i<=n;i++)
    {
        f[i]=f[i-1]*i%p;
    }
    for(int i=1;i<=n;i++)
    {
        s[i]=1;
    }
    for(int i=n;i>=2;i--)
    {
        s[i>>1]+=s[i];
    }
    for(int i=n+1;i<=n*2+1;i++)
    {
        dp[i]=1;
    }
    for(int i=n;i>=1;i--)
    {
        dp[i]=lucas(s[i]-1,s[i*2])%p*dp[i*2]%p*dp[i*2+1]%p;
    }
    cout<<dp[1]<<'\n';
}

标签:int,ll,计数,maxn,错排,杂题,节点,dp
From: https://www.cnblogs.com/captainfly/p/18141663

相关文章

  • rust引用计数智能指针Rc<T>
    大部分情况下所有权是非常明确的:可以准确地知道哪个变量拥有某个值。然而,有些情况单个值可能会有多个所有者。例如,在图数据结构中,多个边可能指向相同的节点,而这个节点从概念上讲为所有指向它的边所拥有。节点在没有任何边指向它从而没有任何所有者之前,都不应该被清理掉。为了启用......
  • 4月杂题
    1.AGC066DAIndependentSet先把\(T\)串看成是\(AB\)和\(B\)的拼接,把\(T\)变成\(S\)的过程看成是\(A\)在移动。考虑\(T\)中一段极长的\(AB\)连续段,你发现最左边的\(A\)一定会往右移,否则可以让这个连续段左边的\(B\)与最左边的\(AB\)交换,这是不劣的。最......
  • Perm 排列计数——Lucas&dfs
    思路:这道题给出的公式看明白后即可得出正解,我们可以把他想象成一颗二叉树,任意一个点的任意一个子孙一直除以2后最终都会到达一终点,终点则为以该点为根的子树的最小值。so——我们可以将根节点作为最后终点即最小值1,设有n个点,左子树选m个点,剩下的给右子树,左子树组合数即C(n-1,m),a......
  • 集合计数
    集合计数题目描述一个有N个元素的集合有2N个不同子集(包含空集),现在要在这2N个集合中取出若干集合(至少一个),使得它们的交集的元素个数为K,求取法的方案数,答案模1000000007。(是质数喔~)输入格式一行两个整数N,K输出格式一行为答案。样例样例输入32样例输出6数据范围与提示......
  • 集合计数——题解
    题目这篇题解的背景。。。(可以跳过,与题目无关)说实话,有点恼,也觉得自己有点唐,在以为自己已经理解了变量意义的情况下(实际上并没有)去推了半天错式子,甚至我推出了他不对时还给自己否定了,昨天晚三还拉着\(9G\)与我一块推。。。,结果上午发觉好像意义理解错了。。。抽象,就当是一种......
  • AT 杂题记录
    byTheBigYellowDuck一些没有做整场或者不值得写比赛记录的杂题。[ABLD]FlatSubsequence子序列问题,容易想到跟最长上升子序列类似的dp方法。设\(f(i)\)为以\(i\)结尾的合法序列的最大长度。转移方程为\[f(i)=\max\limits_{j<i}\{f(j)\}+1\]其中\(j\)要满足\(|a......
  • CF 杂题记录
    byTheBigYellowDuckCF11BJumpingJack由于左右对称,我们可以取绝对值,只考虑数轴正方向的做法。设经过若干次向正方向的跳跃跳到了\(X\)的位置,分类讨论:若\(X=x\),则已经达到了目标位置。若\(X>x\),考虑\(l=X-x\),若\(l\)为偶数则让第\(\dfrac{l}{2}\)次向负方向跳......
  • 「杂题乱刷」CF786C
    题目链接(luogu)题目链接(cf)水2400。首先我们容易看出,答案具有单调性,然后无法使用数据结构进行优化,这时我们可以直接根号分治,发现总是有一段连续的区间数是相同的,因此我们直接根号分治套二分即可AC。参考代码:点击查看代码/*Tips:你数组开小了吗?你MLE了吗?你觉得是贪......
  • diskperf命令是一个用于管理和配置磁盘性能计数器的实用工具,可以帮助你监视和分析磁盘
    diskperf/?DISKPERF[-Y[D|V]|-N[D|V]][\\computername] -Y 在系统重新启动时,将系统设为开启所有磁盘性能计数器。 -YD在系统重新启动时,启用物理驱动器的磁盘性能计数器。 -YV当系统重新启动时,启用逻辑驱动器的磁盘性能计数器或存储数值。 -N 当系统重新......
  • 图论杂题
    Codeforces1572D-BridgeClub题意给出\(n\),有\(2^n\)个点,点权已给出。要求只有两个点的编号的二进制上有且只有一个位置不同时,这两个点有连边。求原图最多选择\(k\)条边的最大(点)权匹配。\(n\le20;k\le100\)Sol考虑边连接的两个点的\(\mathrm{popcount}\)一定不......