BZOJ1978 [BeiJing2010]取数游戏 建图+拓扑序
2017-12-05 18:07
435 查看
很容易想到在可以满足L≤gcd(i,j)的i,j之间连边 但是暴力n2枚举肯定过不了啦 考虑枚举每一个大于L的公因数 我们对于每个数根号n枚举他的因子 对每一个因子建一个vector来存 然后每一个vector里的i和i+1连边 yy一下 这样连就保证了L≤gcd(i,j)的点(i,j)可以到达通过几条边到达 然后我们就在图上跑拓扑序啦
#include<bits/stdc++.h> using namespace std; const int N=1e6+5; inline int read(){ int x=0,f=1;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} return x*f; } int n,l,ans,tot,f[50005],head[50005],in[50005]; queue<int>q; vector<int>b ; struct Egde{ int v,nxt; }e[N*2]; void add(int u,int v){ e[++tot].v=v,e[tot].nxt=head[u],head[u]=tot,in[v]++; } void topsort(){ for(int i=1;i<=n;i++) if(!in[i]) f[i]=1,q.push(i); while(!q.empty()){ int x=q.front();q.pop(); ans=max(ans,f[x]); for(int i=head[x];i;i=e[i].nxt){ int j=e[i].v; f[j]=max(f[j],f[x]+1); if(!--in[j]) q.push(j); } } } int main(){ #ifdef Devil_Gary freopen("in.txt","r",stdin); #endif n=read(),l=read(); for(int p=1,x,i;p<=n;p++){ x=read(); for(i=2;i*i<x;i++) if(x%i==0) b[i].push_back(p),b[x/i].push_back(p); if(i*i==x) b[i].push_back(p);b[x].push_back(p); } for(int i=l;i<N;i++){ if(b[i].size()>1) for(int j=0;j<b[i].size()-1;j++) add(b[i][j],b[i][j+1]); } topsort(); printf("%d",ans); }
相关文章推荐
- bzoj1978 [BeiJing2010]取数游戏 game DP
- BZOJ1978: [BeiJing2010]取数游戏 game
- BZOJ 1978: [BeiJing2010]取数游戏 game
- 【bzoj1978】 BEIJING2010 取数游戏 game dp优化
- 【bzoj1978】【BeiJing2010】取数游戏 game【递推】
- bzoj 1978: [BeiJing2010]取数游戏 game 数学
- bzoj 1978: [BeiJing2010]取数游戏 game -- dp
- 【BZOJ 1978】 [BeiJing2010]取数游戏 game
- BZOJ 1978: [BeiJing2010]取数游戏 game( dp )
- 1978: [BeiJing2010]取数游戏 game
- BZOJ1978: [BeiJing2010]取数游戏 game
- BZOJ 1854 SCOI 2010 游戏 二分图最大匹配
- bzoj1854[Scoi2010]游戏
- [BZOJ 1854] SCOI 2010 游戏 · 二分图匹配
- BZOJ 1854: [Scoi2010]游戏 二分图匹配or并查集
- BZOJ1854 [Scoi2010]游戏
- BZOJ1977 [BeiJing2010组队]次小生成树 Tree
- BZOJ 1854 [Scoi2010]游戏——二分图匹配
- 【BZOJ】2000: [Hnoi2010]stone 取石头游戏
- bzoj 1977: [BeiJing2010组队]次小生成树 Tree 最小生成树+倍增