zoukankan      html  css  js  c++  java
  • 【CF736D】Permutations 线性代数+高斯消元

    【CF736D】Permutations

    题意:有一个未知长度为n的排列和m个条件,第i个条件$(a_i,b_i)$表示第$a_i$个位置上的数可以为$b_i$。保证最终合法的排列的个数是奇数。现在有m个询问,第i个询问是问你在去掉第i个条件后,最终合法的排列数是奇数还是偶数。

    $nle 2000,mle min(C_n^2,500000)$

    题解:神题,滚去学线代了。

    因为在$mod 2$意义下,-1和1相等,所以方案数是什么?如果把所给条件看成一个01矩阵的话,则答案就是这个矩阵对应的行列式的值!而去掉一个条件(a,b)后的答案是什么?1xor行列式的代数余子式$M_{ab}$的值!而题目保证所给矩阵是可逆的,所以我们可以应用性质:

    $A^{*}=|A|A^{-1}$(其中$A^{*}$表示伴随矩阵,$A_{ij}=M_{ji}$)

    所以只需要求出原矩阵的逆即可,可以采用高斯消元。因为是$mod 2$意义下的,所以可以采用bitset优化,时间复杂度$O({n^3over 32})$。

    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    #include <bitset>
    using namespace std;
    int pa[500010],pb[500010];
    bitset<4001> v[2005];
    int n,m;
    inline int rd()
    {
    	int ret=0,f=1;	char gc=getchar();
    	while(gc<'0'||gc>'9')	{if(gc=='-')	f=-f;	gc=getchar();}
    	while(gc>='0'&&gc<='9')	ret=ret*10+(gc^'0'),gc=getchar();
    	return ret*f;
    }
    
    int main()
    {
    	n=rd(),m=rd();
    	int i,j;
    	for(i=1;i<=m;i++)	pa[i]=rd()-1,pb[i]=rd()-1,v[pa[i]][pb[i]]=1;
    	for(i=0;i<n;i++)	v[i][i+n]=1;
    	for(i=0;i<n;i++)
    	{
    		if(!v[i][i])
    		{
    			for(j=i+1;j<n;j++)	if(v[j][i])	break;
    			swap(v[j],v[i]);
    		}
    		for(j=0;j<n;j++)	if(j!=i&&v[j][i])	v[j]^=v[i];
    	}
    	for(i=1;i<=m;i++)
    	{
    		if(v[pb[i]][pa[i]+n])	puts("NO");
    		else	puts("YES");
    	}
    	return 0;
    }
  • 相关阅读:
    laravel Eloquent 模型(也就是我本时说的Model)
    laravel 查询构建器(连贯操作)
    laravel 模版引擎使用
    laravel 数据库操作(表、字段)
    url重写(urlrewrite)的一些系统变量
    apache 图片防盗链
    在线制作api文档
    php 网络爬虫,爬一下花瓣的图片
    laravel 使用 session
    laravel 控制器构造方法注入request对象
  • 原文地址:https://www.cnblogs.com/CQzhangyu/p/8503775.html
Copyright © 2011-2022 走看看