首页 > 其他分享 >[AGC005D] ~K Perm Counting

[AGC005D] ~K Perm Counting

时间:2024-11-11 19:07:35浏览次数:1  
标签:AGC005D Counting int Perm fa le include find mod

题意

求对于所有的 \(i\) 满足 \(|P_i - i| \neq k\),的排列数量,对 \(924844033\) 取模。

\(2 \le n \le 2 \times 10 ^ 3, 1 \le k \le n - 1\)。

Sol

考虑转成 \(n \times n\) 的网格图,那么就是所有 \((i, i + k)\) 以及 \((i, i - k)\) 的格子涂黑不能用。

题意转化为在网格图里放 \(n\) 个车,不能放在黑格子里,互相不攻击的方案数。

考虑尝试把这个限制容斥掉,设 \(f(x)\) 表示我们钦定在黑色格子里放 \(x\) 个车的方案数。

那么答案就是:

\[\sum \sum_{i = 0} ^ n (-1) ^ i f(i) (n - i)! \]

如何计算 \(f\)?注意到我们将每行每列的黑格子连起来,然后就变成了若干条链,不能选择链上相邻的点,直接在链上 \(\texttt{dp{\) 即可。

Code

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <array>
#include <bitset>
#include <vector>
using namespace std;
#ifdef ONLINE_JUDGE

#define getchar() (p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 1 << 21, stdin), p1 == p2) ? EOF : *p1++)
char buf[1 << 23], *p1 = buf, *p2 = buf, ubuf[1 << 23], *u = ubuf;

#endif
int read() {
    int p = 0, flg = 1;
    char c = getchar();
    while (c < '0' || c > '9') {
        if (c == '-') flg = -1;
        c = getchar();
    }
    while (c >= '0' && c <= '9') {
        p = p * 10 + c - '0';
        c = getchar();
    }
    return p * flg;
}
void write(int x) {
    if (x < 0) {
        x = -x;
        putchar('-');
    }
    if (x > 9) {
        write(x / 10);
    }
    putchar(x % 10 + '0');
}
bool _stmer;

const int N = 4e3 + 5, M = 8e6 + 5, mod = 924844033;

array <array <array <int, 2>, N>, N> f;

void Mod(int &x) {
    if (x >= mod) x -= mod;
    if (x < 0) x += mod;
}

namespace Uni {

array <int, M> fa;

int find(int x) {
    if (x == fa[x]) return x;
    return fa[x] = find(fa[x]);
}

void merge(int x, int y) {
    int fx = find(x),
        fy = find(y);
    if (fx == fy) return;
    fa[fy] = fx;
}

void init(int n) {
    for (int i = 1; i <= n; i++)
        fa[i] = i;
}

} //namespace Uni

int getid(int x, int y) { return (x - 1) * ((int)4e3) + y; }

array <bitset <N>, N> vis;
array <int, M> siz;

bool _edmer;
int main() {
    cerr << (&_stmer - &_edmer) / 1024.0 / 1024.0 << "MB\n";
    int n = read(), k = read();
    Uni::init(8e6);
    for (int i = 1; i <= n; i++) {
        if (i + k <= n) vis[i][i + k] = 1;
        if (i - k > 0) vis[i][i - k] = 1;
    }
    for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= n; j++) {
            if (!vis[i][j]) continue;
            if (i + 2 * k <= n && vis[i + 2 * k][j])
                Uni::merge(getid(i, j), getid(i + 2 * k, j));
            if (j + 2 * k <= n && vis[i][j + 2 * k])
                Uni::merge(getid(i, j), getid(i, j + 2 * k));
        }
    }
    for (int i = 1; i <= n; i++)
        for (int j = 1; j <= n; j++)
            if (vis[i][j])
                siz[Uni::find(getid(i, j))]++;
    vector <int> isl;
    for (int i = 1; i <= 8e6; i++)
        if (siz[i]) isl.push_back(siz[i]);
#define upd(x, y) (x += y, Mod(x))
    f[0][0][0] = 1;
    int lst = 0;
    for (auto p : isl) {
        for (int i = lst + 1; i <= lst + p; i++) {
            for (int j = n; ~j; j--) {
                upd(f[i][j][0], f[i - 1][j][0]);
                upd(f[i][j][0], f[i - 1][j][1]);
                if (j)
                    upd(f[i][j][1], f[i - 1][j - 1][0]);
            }
        }
        lst += p;
        for (int i = 1; i <= n; i++)
            upd(f[lst][i][0], f[lst][i][1]), f[lst][i][1] = 0;
    }
    int ans = 0, res = 1;
    for (int i = n; ~i; i--) {
        ans += ((i & 1) ? -1ll : 1ll) * (f[lst][i][0] + f[lst][i][1]) * res % mod, Mod(ans);
        res = 1ll * res * (n - i + 1) % mod;
    }
    write(ans), puts("");
    return 0;
}

标签:AGC005D,Counting,int,Perm,fa,le,include,find,mod
From: https://www.cnblogs.com/cxqghzj/p/18540373

相关文章

  • GIT RE-BASIN: MERGING MODELS MODULO PERMUTATION SYMMETRIES (1)
    在深度学习模型的训练过程中,经常会遇到这样的现象:每次训练,虽然初始值、随机种子、训练数据的顺序不一样,但是得到的loss曲线都差不多,在验证集上的结果也差不多.这篇论文从landscape的角度解释了这个问题:神经网络的losslandscape并不是我们想象中的很混乱、毫无规律,而是在per......
  • nginx权限问题 failed( 13 Permission denied )
    使用nginx代理时,文件一直无法展示,查看nginx的error日志文件显示Permissiondenied,权限问题1.查看nginx启动用户和使用用户是否一致psaux|grepnginx输出的第一列就是用户名称2.打开nginx配置文件#查找nginx.conf文件的位置ps-aux|grepngxin输出记录中有/conf/n......
  • CF2030D QED's Favorite Permutation 题解
    题目传送门前置知识差分解法对于移动,我们可以无脑进行交换来保证移动,然后将中途交换的位置再交换回去。通过手摸不难发现,\(p_{i}\)能移动到\(i\)当且仅当\(s_{\min(i,p_{i})\sim\max(i,p_{i})}\)中不含有LR子串。反向考虑,即LR子串不被上述区间包含,差分判断即可。......
  • 解决Nginx出现403 forbidden (13: Permission denied)报错的四种方法
    我是在在本地用虚拟机中通过yum安装nginx的,安装一切正常,但是访问时报403,于是查看nginx日志,路径为/var/log/nginx/error.log。打开日志发现报错Permissiondenied,详细报错如下:1.open()"/data/www/1.txt"failed(13:Permissiondenied),client:192.168.1.194,server:www.web......
  • SP15637 GNYR04H - Mr Youngs Picture Permutations 解析
    SP15637GNYR04H-MrYoungsPicturePermutations解析题目链接分析题目性质大意就是给\(k\)排然后每个数列单调,每个横列单调,求满足这样排列的方案数。我们发现:与其为每个位置分配某个学生不如考虑将每个学生分给某个位置。思路根据以上,不妨设:\(f_{a_1,a_2,a_3,a_4,a_5}......
  • 38_api_intro_stock_cn_stockcnindexperminutes
    A股指数分时行情数据API数据接口多维度分时指标,指数分时,多时间区间查询参数。1.产品功能支持所有指数数据查询;支持指数分时数据查询;多时间维度分时数据;多维度的统计时间以及数据结果;秒级查询性能;数据持续更新与维护;全接口支持HTTPS(TLSv1.0/v1.1/v1.2/v1.3);......
  • IDA修改WeChatAppEx,打补丁提示 Permission denied
    手贱,升级了下PC微信的版本,结果导致微信内置浏览器上的开发者模式(Devtools)失效,有时候需要在微信环境中看下别人的HTML不是很方便,特别是对于微信视频号中的视频更是看不到。新版本的已经没有【检查】这个选项了操作步骤如下:复制一份WeChatAppEx.exe,退出登录的PC微信,使用IDA......
  • 数组排序简介-计数排序(Counting Sort)
    基本思想        通过统计数组中每个元素在数组中出现的次数,根据这些统计信息将数组元素有序的放置到正确位置,从而达到排序的目的。算法步骤计算排序范围:遍历数组,找出待排序序列中最大值元素 nums_max和最小值元素 nums_min,计算出排序范围为 nums_max−nums_min......
  • 若依 v-hasPermi v-if insertBefore
    背景:项目框架用的ruoyi,最近测试提了一个bug:关闭开启的按钮权限,新建数据后会出现按钮(并没有报错),但是刷新后又消失了。定位问题:按钮权限通过v-hasPermi控制,之前的页面也是这么用的没有复现,区别在于这里用了v-if。控制变量法确定就是v-if和v-hasPermi同时使用造成,检索解决方案是......
  • DRF-Permission组件源码分析及改编源码
    1.权限组件源码分析PS:下列源码为了方便理解都进行了简化,只保留了权限相关的代码由于视图函数中继承了APIView,因此permission_classes可在视图类中进行重写。注意点:执行权限校验前,已执行了认证流程。因此此时可通过self.user获取用户对象(认证通过的情况)2.实践:编写一......