bzoj4602: [Sdoi2016]齿轮

来源:互联网 发布:百战天下数据 编辑:程序博客网 时间:2024/06/09 16:50

题外话

  浏览器坏掉了…昨天一下午没发题解,现在只好一块发出去。

简述

  来做一下传说中的送分题。。。我可能比较智障所以调了好长时间,想是很好想
  首先考虑double暴力,这个没啥好说的,暴力dfs,竟然有人用double水过去了!
  把1100的素数乘起来发现已经爆了long long,所以不可能求出lcm然后乱搞,那怎么办??
  看下数据规模,发现T×M竟然才105?也就是说我们还有再加两个0的余地,嗯…立马就想到每个数用素数的幂表示。
  然后就AC了。

代码

//分解质因数+dfs#include <cstdio>#include <algorithm>#define maxn 100000#define abs(x) (x>0?x:-x)using namespace std;int N, M, T, head[maxn], nex[maxn], to[maxn], w1[maxn], w2[maxn], tot, prime[100],    vis[maxn];struct num{    int q[100], fu;    void clear(){for(int i=1;i<=*prime;i++)q[i]=0;}}w[maxn], nb[123], big;int gcd(int a, int b){return !b?a:gcd(b,a%b);}num operator*(num a, int b){    int i;    num c;    c.clear();    for(i=1;i<=*prime;i++)c.q[i]=a.q[i]+nb[abs(b)].q[i];    c.fu=a.fu^(b<0);    return c;}num operator/(num a, int b){    int i;    num c;    c.clear();    for(i=1;i<=*prime;i++)c.q[i]=a.q[i]-nb[abs(b)].q[i];    c.fu=a.fu^(b<0);    return c;}bool cmp(num a, num b){    int i;    if(a.fu!=b.fu)return false;    for(i=1;i<=*prime;i++)if(a.q[i]!=b.q[i])return false;    return true;}void adde(int a, int b, int v1, int v2){    to[++tot]=b;nex[tot]=head[a];head[a]=tot;    w1[tot]=v1, w2[tot]=v2;}void init(){    int i, j, t;    for(i=2;i<=100;i++)    {        for(j=2;j*j<=i;j++)if(i%j==0)break;        if(j*j>i)prime[++*prime]=i;    }    for(i=2;i<=100;i++)        for(j=1;j<=*prime;j++)            for(t=i;t%prime[j]==0;nb[i].q[j]++,t/=prime[j]);    for(i=1;i<=100;i++)big.q[i]=100;}void build(){    int i, j, u, v, x, y;    scanf("%d%d",&N,&M);    for(i=1;i<=tot;i++)nex[i]=0;    for(i=1;i<=N;i++)head[i]=0;    tot=0;    for(i=1;i<=M;i++)scanf("%d%d%d%d",&u,&v,&x,&y), adde(u,v,x,y), adde(v,u,y,x);    for(i=1;i<=N;i++)vis[i]=0;}bool dfs(int pos){    int p; num t;    vis[pos]=1;    for(p=head[pos];p;p=nex[p])    {        t=w[pos]/w1[p]*w2[p];        if(vis[to[p]])        {            if(!cmp(w[to[p]],t))return false;        }        else        {            w[to[p]]=t;            if(!dfs(to[p]))return false;        }    }    return true;}int main(){    int T, i, j; bool f;    init();    scanf("%d",&T);    for(i=1;i<=T;i++)    {        build();        w[1]=big;        f=dfs(1);        for(j=1;j<=N;j++)if(!vis[j])f=f and dfs(j);        printf("Case #%d: ",i);        printf(f?"Yes\n":"No\n");    }    return 0;}
0 0
原创粉丝点击