But my words, like s|

MessageBoxA

园龄:4年10个月粉丝:4关注:0

2024-05-09 23:27阅读: 15评论: 0推荐: 0

NOI模拟 序列

涉及知识点:数论,图论转化建图

题意

有一串长为 n (103) 序列 a,给出 m (103) 个条件,每条条件形如 gcd(ai,aj)=k,问是否存在这样的序列满足所有条件。保证不存在重复的 (ai,aj) 对。

思路

把题目给出的所有关系建成图,点 i 代表 aigcd(ai,aj)=k 转化为 ij 边权为 k 的边。将每个节点的点权设为与它相连的所有边边权的最小公倍数,可以证明,假如条件合法,这将是最小的合法值。

然后再遍历每条边,记为 (u,v,k),判断 uv 点权的 gcd 是否为 k,可以发现:

  • 如果 k<gcd,因为 uv 的点权已经是最小,无法再变小,因此它们的 gcd 也不可能再变小,该情况不合法。
  • 如果 k=gcd,该情况符合题意,合法。
  • 如果 k>gcd,不存在这种情况,因为 uv 的点权都为 k 的倍数,它们的 gcd 无论如何都不可能小于 k

因此,判断每条边即可。

代码

代码似乎会爆精度,莫名其妙就过了,有bug慎阅

#include<bits/stdc++.h>
using namespace std;
#ifdef ONLINE_JUDGE
#define getchar __getchar
inline char __getchar(){
    static char ch[1<<20],*l,*r;
    return (l==r&&(r=(l=ch)+fread(ch,1,1<<20,stdin),l==r))?EOF:*l++;
}
#endif
template<class T>inline void rd(T &x){
    T res=0,f=1;
    char ch=getchar();
    while(ch<'0' || ch>'9'){if(ch=='-')f=-1; ch=getchar();}
    while('0'<=ch && ch<='9'){res=res*10+ch-'0';ch=getchar();}
    x=res*f;
}
template<class T>inline void wt(T x,char endch='\0'){
    static char wtbuff[20];
    static int wtptr;
    if(x==0){
        putchar('0');
    }
    else{
        if(x<0){x=-x;putchar('-');}
        wtptr=0;
        while(x){wtbuff[wtptr++]=x%10+'0';x/=10;}
        while(wtptr--) putchar(wtbuff[wtptr]);
    }
    if(endch!='\0') putchar(endch);
}
typedef long long LL;
typedef __int128_t int128;
const int MAXN=1e3+5;
int n,m,head[MAXN],ecnt=1;
int128 val[MAXN];
struct EDGE{
    int v,nxt;
    int128 w;
}e[MAXN<<2];
inline void add(const int& u,const int& v,const int128& w){
    e[++ecnt].v=v;
    e[ecnt].w=w;
    e[ecnt].nxt=head[u];
    head[u]=ecnt;
}
inline int128 __lcm(int128 x,int128 y){
    return x*y/__gcd(x,y);
}
inline void solve(){
    memset(head,0,sizeof(head));
    ecnt=1;
    
    rd(n);rd(m);
    for(int i=1,u,v;i<=m;i++){
        int128 w;
        rd(u);rd(v);rd(w);
        add(u,v,w);add(v,u,w);
    }

    for(int i=1;i<=n;i++){
        val[i]=1;
        for(int j=head[i];j;j=e[j].nxt){
            val[i]=__lcm(val[i],e[j].w);
        }
    }

    for(int i=2;i<=ecnt;i+=2){
        if(__gcd(val[e[i].v],val[e[i^1].v])!=e[i].w){
            puts("No");
            return;
        }
    }
    puts("Yes");
}
int main(){
    int t;
    rd(t);
    while(t--) solve();
    return 0;
}

本文作者:MessageBoxA

本文链接:https://www.cnblogs.com/SkyNet-PKN/p/18183327

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   MessageBoxA  阅读(15)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
收起
  1. 1 evening Corn Wave
  2. 2 Группа крови Кино
  3. 3 The Sound Of Silence Simon & Garfunkel
  4. 4 dB doll YUE.STEVEN
Группа крови - Кино
00:00 / 00:00
An audio error has occurred, player will skip forward in 2 seconds.