首页 > 其他分享 >CF1835D Doctor's Brown Hypothesis 题解

CF1835D Doctor's Brown Hypothesis 题解

时间:2023-12-01 15:55:39浏览次数:41  
标签:Brown int 题解 scc read depth CF1835D buc dis

题目链接

点击打开链接

题目解法

首先只有在一个强联通分量里的点对才可能合法,因此我们这里说的图默认为强联通图
但是上面的条件成立只需要满足 \(k\ge n\),考虑用好 \(k\) 可以认为是极大的性质

所以说我们可以通过图中所有的环 \(+\) 路径来凑出 \(k\)
不难发现,所有的环能构成的长度形如 \(\sum len_ix_i\),\(len\) 为环长,\(x_i\ge 0\)
因为 \(k\) 足够大,所以能构成长度 \(l\) 的充要条件为 \(\gcd(len_i)|l\)

求出有向图所有环长度的 \(\gcd\) 是这道题
具体过程是:建出一棵生成树,对于所有的非树边 \((x,y,z)\),\(dis_x+z-dis_y\) 求 \(\gcd\),其中 \(dis_x\) 为 \(root\) 到 \(x\) 的距离
证明我只会证充分性
还是说明一下充分性,可以帮助理解下面给出的结论
在强联通分量内,\(D_{rt,x}+D_{x,rt}\equiv 0(\mod g)\),\(g\) 为所有环长的 \(\gcd\),对于一条横叉边,不难得出 \(D_{y,rt}+D_{rt,x}+z\equiv 0(\mod g)\),所以 \(D_{rt,x}-D_{y,rt}+z\equiv 0(\mod g)\)

可以猜出点对 \((x,y)\) 合法的充要条件为 \(dis_x-dis_y\equiv k\%g\) 且 \(dis_y-dis_x\equiv k\%g\)
对于 \(k\%g=0\) 和 \(k\%g=\frac{g}{2}\) 分类讨论即可

时间复杂度 \(O(n)\)

#include <bits/stdc++.h>
#define F(i,x,y) for(int i=(x);i<=(y);i++)
#define DF(i,x,y) for(int i=(x);i>=(y);i--)
#define ms(x,y) memset(x,y,sizeof(x))
#define SZ(x) (int)x.size()-1
#define pb push_back
using namespace std;
typedef long long LL;
typedef unsigned long long ull;
typedef pair<int,int> pii;
template<typename T> void chkmax(T &x,T y){ x=max(x,y);}
template<typename T> void chkmin(T &x,T y){ x=min(x,y);}
template<typename T> void read(T &FF){
    FF=0;int RR=1;char ch=getchar();
    for(;!isdigit(ch);ch=getchar()) if(ch=='-') RR=-1;
    for(;isdigit(ch);ch=getchar()) FF=(FF<<1)+(FF<<3)+ch-48;
    FF*=RR;
}
const int N=100100,M=200100;
int n,m;
LL k;
int e[M],ne[M],h[N],idx;
int low[N],dfn[N],dfs_clock,stk[N],top;
int scc_num[N],scc_cnt;
void tarjan(int u){
    low[u]=dfn[u]=++dfs_clock,stk[++top]=u;
    for(int i=h[u];~i;i=ne[i]){
        int v=e[i];
        if(!dfn[v]) tarjan(v),low[u]=min(low[u],low[v]);
        else if(!scc_num[v]) low[u]=min(low[u],dfn[v]);
    }
    if(dfn[u]==low[u]){
        scc_num[u]=++scc_cnt;
        while(stk[top]!=u) scc_num[stk[top]]=scc_cnt,top--;
        top--;
    }
}
vector<int> scc[N],G[N];
int depth[N],g,buc[N];
bool vis[N];
void dfs(int u){
    vis[u]=1;
    for(auto v:G[u])
        if(!vis[v]) depth[v]=depth[u]+1,dfs(v);
        else g=__gcd(g,depth[u]+1-depth[v]);
}
void add(int x,int y){ e[idx]=y,ne[idx]=h[x],h[x]=idx++;}
int main(){
    read(n),read(m),read(k);
    ms(h,-1);
    F(i,1,m){
        int x,y;read(x),read(y);
        add(x,y);
    }
    F(i,1,n) if(!dfn[i]) tarjan(i);
    F(i,1,n) scc[scc_num[i]].pb(i);
    F(i,1,n) for(int j=h[i];~j;j=ne[j]) if(scc_num[i]==scc_num[e[j]]) G[i].pb(e[j]);
    LL ans=0;
    F(i,1,scc_cnt){
        g=0,dfs(scc[i][0]),g=abs(g);
        if(!g) continue;
        for(auto x:scc[i]) depth[x]%=g,buc[depth[x]]++;
        if(k%g==0) F(j,0,g-1) ans+=1ll*buc[j]*(buc[j]+1)/2;
        if((~g&1)&&k%g==g/2) F(j,g/2,g-1) ans+=1ll*buc[j]*buc[j-g/2];
        F(j,0,g-1) buc[j]=0;
    }
    printf("%lld\n",ans);
    fprintf(stderr,"%d ms\n",int(1e3*clock()/CLOCKS_PER_SEC));
    return 0;
}

标签:Brown,int,题解,scc,read,depth,CF1835D,buc,dis
From: https://www.cnblogs.com/Farmer-djx/p/17869892.html

相关文章

  • CF249题解
    CF249linkCF249ElinkCF249E题意给你一个形如下图的矩阵并有\(T\)组询问每组询问给出\(x_1,y_1,x_2,y_2\)。求\(\sum_{i=x_1}^{x_2}\sum_{j=y_1}^{y_2}A[i][j]\)。其中\(A[i][j]\)表示在矩阵中的数。\(T\leq10^5\)\(1\leqx_1\leqx_2\leq10^9\)\(1\leqy_1......
  • P7110 晚秋绝诗 题解
    好有意思的题目啊。出题人太厉害了。思路考虑一个结论:我们将两个没插旗的点与中间的点称为一段,其中中间的点必须全部插旗。那么这一段如果已知两座山的高度,就一定可以得知所有的高度。考虑为什么。加入这一段是\(a\simb\)。\[\begin{cases}h_a+h_{a+2}=2\timesh_{a+1}......
  • Advent of Code 2023题解 [Mathematica/Python]
    Day1Part1(*读取文件*)lines=ReadList["E:\\ExplorerDownload\input.txt",String];(*计算校准值*)calibrationValues=ToExpression[StringJoin[#[[1]],#[[-1]]]]&/@(StringCases[#,DigitCharacter]&/@lines);(*打印总和*)Pri......
  • CF1198题解
    CF1198CodeforcesRound576(Div.1)CF1198AlinkCF1198A题意有一种数字化一段录音的常用方式,是记录每一个时刻的强度值。这些非负的强度值就可以代表一段音频对于一段音频,若有\(K\)个不同的强度值,那么每一位我们都需要\(k=\lceil\log_2K\rceil\)\(\text{bit}\)来存......
  • [AGC052B] Tree Edges XOR 题解
    题目链接点击打开链接题目解法怎么感觉这场\(B\)比\(C\)思维量更大考虑一步很妙的操作:把边权变成点权,以达到简化操作的目的使每条边的边权为两端点的异或和,手画一下可以发现,操作简化成了交换两端点的点权我们定义\(d_{1/2,i}\)定义为在\(1/2\)树上,\(i\)到根的权值......
  • CF1684题解
    CF1684CodeforcesRound792(Div.1+Div.2)CF1684AlinkCF1684A题意有一个用十进制表示的没有前导零的正整数\(n\)。Alice和Bob正在用这个数玩一个游戏。Alice先手,他们轮流进行游戏。在她的这一轮中,Alice应该交换这个数中的任何不同位置的两位。轮到Bob时,他每次......
  • [AGC052C] Nondivisible Prefix Sums 题解
    题目链接点击打开链接题目解法好题!一个序列是不合法的,必定满足某些结论,我们不妨猜测一下首先如果和为\(P\)的倍数,必定不合法然后手玩几个可以发现,最极限的情况是\(P-1\)个\(1\;+\;\)\(b_i\;+\;\)\(P-b_i\)如果在这个情况下再加一个\(1\),就爆了其中\(1\)可以替......
  • CF689题解
    CF689CodeforcesRound361(Div.2)CF689AlinkCF689A题意题目描述迈克在海滩游泳时不小心将手机放入水中。他买了一个带有老式键盘的手机。键盘只有十个数字大小的键,位于以下方式:1234567890联系人与他的旧手机一起消失了,他现在只能记住他的手指......
  • 商家转账到零钱全攻略:开通、使用、区别与常见问题解答
    一、商家转账到零钱功能介绍微信作为中国最受欢迎的社交平台之一,其支付功能也相当强大。其中,商家转账到零钱功能可以让商家直接将款项转入用户的微信零钱,方便快捷。本文将详细介绍商家转账到零钱的功能、开通条件、使用方法以及常见问题解答。二、商家转账到零钱场景说明商家转......
  • axios(ajax)发送请求响应码200,但获取不到数据,无法加载响应数据: No datafound for res
    问题截图:没有响应数据控制台报错其实是由于浏览器的跨域资源共享(CORS)策略导致,前后端跨域请求是不行的。什么是域,看页面的url,比如https://www.baidu.com/下的网页都是属于baidu.com这个域。如果你是和我一样是从本地文件打开html的方式来调试ajax,那么一定会出现这个问题,因为本......