首页 > 其他分享 >QOJ61 Cut Cut Cut! 题解

QOJ61 Cut Cut Cut! 题解

时间:2023-09-20 12:55:55浏览次数:58  
标签:Cut int 题解 ll QOJ61 vec mod out deg

题面。

题解

假设 \(1\) 号点有 \(d\) 条出边,给 \(d\) 条出边赋 \(d\) 个独立的单位向量,接下来,每个出边记作入边的随机线性组合,那么对于第 \(i\) 个点,答案就是入边生成的线性空间的秩。

正确性证明:

对于每个点考虑,假设现在考虑 \(i\) 号点,将其入边集合记作 \(E1_{i}\) ,出边集合记作 \(E2_i\) ,对于所有的 \(e1\in E1,e2\in E2\),有一个随机变量 \(val_{e1,e2}\) 表示 \(e1\) 这条入边在 \(e2\) 这条出边里组合的系数(先将其视为未知数。)。

假设 \(i\) 的答案为 \(k\) ,那么只需要证明 \(i\) 处入边构成的多项式矩阵的秩是 \(k\) ,这样用 \(Schwartz-Zippel\) 引理就知道每个元代随机值的情况下也有 \(1-(d/mod)\) 的概率秩为 \(k\) ,\(d\) 为多项式次数, \(mod\) 为选取的大素数模数。

在本题中,这个多项式矩阵的次数不超过 \(n\) ,那么用来测试秩是否为 \(k\) 的多项式次数不超过 \(20n\) ,因此选取的 \(mod\) 只要远大于 \(20n\) 即可保证正确率较高,那么根据\(Schwartz-Zippel\) 引理,我们可以随机赋权(赋那个组合的系数。)。

秩小于等于最小割是显然的,证明考虑入边的向量肯定是割边的向量的线性组合,那秩不能超过割边的个数。

再证秩大于等于最大流,假设最大流为 \(k1\) ,假设最大流上这些随机变量赋成 \(1\) ,其他的赋成 \(0\) ,那么矩阵就只剩下 \(k1\) 个位置是 \(1\) 了,而且刚好不同行不同列,所以此时秩为 \(k1\) 。而多项式矩阵存在一种赋值方法使其秩为 \(k1\) ,那么原本的秩必然大于等于 \(k1\) ,因为原本线性相关的项赋值后也必然线性相关。

那么根据最小割最大流定理,有 \(k=k1\) ,所以秩,最小割,最大流均相等。

代码

#include<bits/stdc++.h>
#define For(i,l,r) for(int i=(l);i<=(r);++i)
#define ReFor(i,r,l) for(int i=(r);i>=(l);--i)
const int N=100010;
const int mod=1000000007;
typedef long long ll;
using namespace std;
int n,m,out_deg_1;
vector<int> G[N];
mt19937_64 rnd(20070810);
ll qpow(ll a,int b)
{
    ll res=1;
    while(b)
    {
        if(b&1)(res*=a)%=mod;
        (a*=a)%=mod;b>>=1;
    }
    return res;
}
template<typename T1,typename T2>
void Add(T1 &a,T2 b){a+=b;if(a>=mod)a-=mod;return;}
template<typename T1,typename T2>
void Sub(T1 &a,T2 b){a-=b;if(a<0)a+=mod;return;}
struct Linear_Basis
{
    vector<ll> vec[21];
    void clear(){For(i,0,out_deg_1-1)vec[i].clear();return;}
    void init(){For(i,0,out_deg_1-1)vec[i].resize(out_deg_1);return;}
    void insert(vector<ll> a)
    {
        ReFor(i,out_deg_1-1,0)
        {
            if(a[i]==0)continue;
            if(vec[i][i]!=0)
            {
                ll _=a[i];
                For(j,0,i){ll delta=_;(delta*=vec[i][j])%=mod;Sub(a[j],delta);}
                continue;
            }
            else if(vec[i][i]==0)
            {
                ll inv_a_i=qpow(a[i],(mod-2));
                For(j,0,i)(a[j]*=inv_a_i)%=mod;
                For(j,0,i)vec[i][j]=a[j];return;
            }
        }
        return;
    }
    int get_rank(){int res=0;For(i,0,out_deg_1-1)res+=vec[i][i];return res;}
}a[N];
int main()
{
    ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
    cin>>n>>m;
    For(i,1,m){int x,y;cin>>x>>y;G[x].emplace_back(y);}
    {
        out_deg_1=0;for(auto y:G[1])++out_deg_1;For(i,1,n){a[i].clear();a[i].init();}For(i,0,out_deg_1-1)a[1].vec[i][i]=1; 
    };
    For(i,1,n)
    {
        for(auto y:G[i])
        {
            vector<ll> tmp;tmp.clear();tmp.resize(out_deg_1);
            For(j,0,out_deg_1-1)
            {
                ll rnd_val=(rnd()%mod);if(rnd_val<0)rnd_val+=mod;
                For(k,0,out_deg_1-1){ll delta=rnd_val;(delta*=a[i].vec[j][k])%=mod;Add(tmp[k],delta);}
            }
            a[y].insert(tmp);
        }
    }
    For(i,2,n){int ans_i=a[i].get_rank();cout<<ans_i<<" ";}return 0;
}

标签:Cut,int,题解,ll,QOJ61,vec,mod,out,deg
From: https://www.cnblogs.com/llzer/p/17717045.html

相关文章

  • 9.20周三(动手动脑问题解决)
    无法编译原因:没有默认构造推出结论:当你给类提供了一个自定义的构造方法,导致系统不在提供默认构造方法了,需要自己提供初始化测试packageorg.example;publicclassInitializeBlockClass{publicintfield=100;{field=200;}publicInitiali......
  • Acwing393. 雇佣收银员 题解 差分约束
    题目链接:https://www.acwing.com/problem/content/description/395/解题思路:差分约束。为了方便起见,定义第\(i\)个时间段为\(i-1:00\)到\(i:00\)这个时间段。首先,为了方便开一个额外的点,令\(R_i\)对应为题目中的\(R(i+1)\),即\(R_i\)表示\(i-1:00\)到\(i:00\)这......
  • 微软自带拼音输入法不显示选字框的问题解决
    运行框、聊天框都不显示右击右下角的图标-设置-常规-兼容性拉到最下面有个“兼容性”,勾选即可现在OK了......
  • CF1767C Count Binary Strings 题解
    CF1767CCountBinaryStrings题解Foreword感谢@樱雪喵、@swiftc两位大佬的耐心指导。Links洛谷CodeforcesDescription有一个长度为\(n\)的01串\(s\)(下标从\(1\)开始)和一些限制\(a_{i,j}(1\lei\lej\len)\)。\(a_{i,j}\)的含义如下:\(a_{i,j}=\)含义......
  • 【POJ 3278】Catch That Cow 题解(深度优先搜索)
    农夫约翰已被告知一头逃亡奶牛的位置,并想立即抓住她。他从一条数字线上的N点(0≤N≤100000)开始,奶牛在同一条数字线上的K点(0≥K≤100000)。农夫约翰有两种交通方式:步行和坐车。*步行:FJ可以在一分钟内从任何点X移动到点X-1或X+1*坐车:FJ可以在一分钟内从任何X点移动到2×X点。如果奶......
  • 「2019 集训队互测 Day 3」操作序列计数 题解
    简化题意:对于每一个$L$,求出有多少个长度为$L+1$的非负整数序列$a$,满足$\sum_{i=0}^{L}a_ik^i\leqn$,并且$a_{L}>0$。我们注意题目要求的和是小于等于一个数,这不太方便。我们可以把它转化成和等于一个数的形式,其实就是和为$nk$的方案数,这就相当于在最后的和后面乘上一......
  • 【题解】CF1817 合集
    CF1817AAlmostIncreasingSubsequence考虑几乎上升的序列的长度,就是我们的区间长度减去\(a_{i-2}\geqa_{i-1}\geqa_i\)的对数,然后维护即可,当然个人感觉自己的代码有点长,可以考虑看洛谷题解代码code:#include<bits/stdc++.h>usingnamespacestd;constintNN=2e5+......
  • CF840C 题解
    一、题目描述:给你一个长度为$n$的序列$a_1\sima_n$,$0\lea_i\le1\times10^9$。求有多少种$1\simn$的全排列$b$,使得对于$i\in[2,n],a_{b_i}\timesa_{b_{i-1}}$不是完全平方数。本题中完全平方数的定义:若存在某个整数$k$,使得$k^2=x$,则$x$是一个......
  • 9.18CF1817题解
    9.18CF1817题解A.AlmostIncreasingSubsequence题意给定长度为\(n\)一个序列\(a\)以及\(q\)次询问,每次询问给出\(l\)和\(r\),找出序列\(a\)在\([l,r]\)内最长的几乎递增子序列。对于几乎递增的定义:如果一个序列中不存在连续的三个数\(x\),\(y\),\(z\),使得\(x\g......
  • 题解 AGC058B 【Adjacent Chmax】
    postedon2022-08-1500:08:56|under题解|sourceproblem一个长为\(n\)的排列\(P\),每次可以选择一个\(i\),令\(v=\max(P_i,P_{i+1})\),使\(P_i=P_{i+1}=v\),求若干次操作后有多少种不同的序列。\(1\leqn\leq5000\)。solution显然地,对于一个\(P_i\),它要么被完全覆盖......