Processing math: 100%

bzoj4563 HAOI2016放旗子

bzoj传送门
已知了"任意两个障碍不在同一行,任意两个障碍不在同一列",如果我们按每列只能放一个来考虑,那么这n个障碍一定是一个排列,那么也就是“每一列只能放一个,有(n1)个位置可以放,每一列不能放的位置都不同”,很轻易可以想到错排问题(n个位置,每个位置上的数不能为位置的编号),本质相同,直接套错排问题求解即可。由于答案过大,我们考虑对……抱歉,此题没有模数,请自觉写高精度。
代码:

#include<cstdio>
#include<cstring>
#define max(a,b) (a>b?a:b)
int n,mp,pps=1000;
struct Bignum {
    int num[104];
    void clear() {
        memset(num,0,sizeof(num));
        num[0]=num[1]=1;
    }
    Bignum operator*(const int &a)const {
        Bignum c;memset(c.num,0,sizeof(c.num));
        c.num[0]=num[0];
        for(int i=1;i<=num[0];i++) {
            c.num[i]+=num[i]*a;
            c.num[i+1]+=c.num[i]/pps;
            c.num[i]%=pps;
        }
        if(c.num[c.num[0]+1])c.num[0]++;
        return c;
    }
    Bignum operator+(const Bignum &a)const {
        Bignum c;memset(c.num,0,sizeof(c.num));
        c.num[0]=max(num[0],a.num[0]);
        for(int i=1;i<=c.num[0];i++) {
            c.num[i]+=num[i]+a.num[i];
            c.num[i+1]+=c.num[i]/pps;
            c.num[i]%=pps;
        }
        if(c.num[c.num[0]+1])c.num[0]++;
        return c;
    }
    void print() {
        printf("%d",num[num[0]]);
        for(int i=num[0]-1;i>0;i--)
            printf("%03d",num[i]);
    }
}a,b,c;
int main()
{
    scanf("%d",&n);
    for(int i=1;i<=n;i++)for(int j=1;j<=n;j++)scanf("%d",&mp);
    a.clear(),a.num[1]=0,b.clear();
    for(int i=3;i<=n;i++)c=(a+b)*(i-1),a=b,b=c;
    b.print();
}
posted @   蒟蒻--lichenxi  阅读(106)  评论(0编辑  收藏  举报
编辑推荐:
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
阅读排行:
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
点击右上角即可分享
微信分享提示