链接:
https://www.nowcoder.com/acm/contest/152/B
来源:牛客网
来源:牛客网
题目描述
点点现在有n个软件包。他想设计一个软件包管理器。不可避免地,他要解决软件包之间的依赖问题。
一开始这些软件包之间没有依赖关系。但是每次点点会添加一条依赖关系a,b,表示软件包a依赖b。当这些软件包的依赖关系没有环的时候,那么这个软件包的管理器是好的,否则就是不好的。
环的定义如下:
对于任意k(k≥2)个软件包{a 1,a 2,...,a k},若对于所有的i<k满足a i依赖a i+1,且a 1=a k成立,则这k个软件包构成一个环。
点点想让你回答他每次加入一条依赖关系之后这个软件包是不是好的,如果是好的那么输出1,否则输出0。同时,点点希望他在加入每一条关系之后你都能回答他,所以他会在读入中对数据进行加密。你只有回答了问题才能知道下一条依赖关系是什么。
一开始这些软件包之间没有依赖关系。但是每次点点会添加一条依赖关系a,b,表示软件包a依赖b。当这些软件包的依赖关系没有环的时候,那么这个软件包的管理器是好的,否则就是不好的。
环的定义如下:
对于任意k(k≥2)个软件包{a 1,a 2,...,a k},若对于所有的i<k满足a i依赖a i+1,且a 1=a k成立,则这k个软件包构成一个环。
点点想让你回答他每次加入一条依赖关系之后这个软件包是不是好的,如果是好的那么输出1,否则输出0。同时,点点希望他在加入每一条关系之后你都能回答他,所以他会在读入中对数据进行加密。你只有回答了问题才能知道下一条依赖关系是什么。
输入描述:
第一行两个正整数n,m (1≤n≤100,000, 1≤m≤200,000),表示软件包的个数和操作个数。软件包的标号为1到n。 接下来m行,每行两个正整数u’, v’,表示加密后的依赖关系,保证u’≠v’。如果上一个回答为ans,实际的依赖关系为u, v,那么u’=(u+ans) mod n+1, v’=(v+ans) mod n+1。一开始的ans为0。
输出描述:
输出m行,每行一个数0或1,表示加入了一条依赖关系之后的回答。
题解:题目中的加密和解密无非就是给你一个强制在线的假象,但简单的思考后你会发现完全可以离线来做,因为答案只有0或者1,并且在出现0之后就一直是0了,因此我们考虑第一个0出现的位置即可,然后判环直接爆搜。。。
#include<vector>
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
#define ll long long
#define mod 1000000007
#define maxn 100005
vector<int>q[maxn];
int n,m,ans,a[2*maxn],b[2*maxn],vis[maxn],flag,c[2*maxn],d[2*maxn];
void dfs(int x)
{
if(flag) return;vis[x]=1;
for(int i=0;i<q[x].size();i++)
{
if(vis[q[x][i]]==2) continue;
if(vis[q[x][i]]==1)
{
flag=1;
continue;
}
dfs(q[x][i]);
}
vis[x]=2;
}
int check(int x)
{
flag=0;
for(int i=1;i<=n;i++)
q[i].clear(),vis[i]=0;
c[1]=a[1]-1;d[1]=b[1]-1;
for(int i=2;i<=x;i++)
{
c[i]=a[i]-2;
if(c[i]==0) c[i]=n;
if(c[i]==-1) c[i]=n-1;
d[i]=b[i]-2;
if(d[i]==0) d[i]=n;
if(d[i]==-1) d[i]=n-1;
}
for(int i=1;i<=x;i++)
q[c[i]].push_back(d[i]);
for(int i=1;i<=n;i++)
{
if(!vis[i]) dfs(i);
if(flag) return 0;
}
return 1;
}
int main(void)
{
scanf("%d%d",&n,&m);
for(int i=1;i<=m;i++)
scanf("%d%d",&a[i],&b[i]);
int l=1,r=m,mid;
while(l<=r)
{
mid=(l+r)/2;
if(check(mid))
ans=mid,l=mid+1;
else
r=mid-1;
}
for(int i=1;i<=ans;i++)
printf("1\n");
for(int i=ans+1;i<=m;i++)
printf("0\n");
return 0;
}