bzoj4602: [Sdoi2016]齿轮

xiaoxiao2021-02-28  84

题外话

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

简述

  来做一下传说中的送分题。。。我可能比较智障所以调了好长时间,想是很好想   首先考虑 double 暴力,这个没啥好说的,暴力 dfs ,竟然有人用 double 水过去了!   把 1 100的素数乘起来发现已经爆了 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; }
转载请注明原文地址: https://www.6miu.com/read-54811.html

最新回复(0)