虽然AC了。
但是我认为这道题是有问题的。
紫书上说:
先把x设为0,再把x设为1,如果二者的输出相同,整个电路肯定是常数,任意输出一种方案即可。
可是事实上并不是这样。
比如这组数据
1
6 5
-2 -3 -4 -5 -1 1 -6 2 3 4
满足紫书上的条件,然而整个电路却并不是常数。
加入如下的代码来debug。
for(int i=0;i<=n;i++)
printf("%d:%d\n",i,run(i));
遍历x的位置,输出电路结果。
1
6 5
-2 -3 -4 -5 -1 1 -6 2 3 4
0:0
1:1
2:1
3:0
4:0
5:0
6:0
000000
Process returned 0 (0x0) execution time : 6.821 s
Press any key to continue.
我们可以发现,虽然满足紫书上的条件,但在中间的过程中出现了先变成1再变成0的情况。
如果强行用二分来解决这种情况下的问题,那么就不一定能得到正确的结果了。
看了网上许多人AC的代码,都不能解决这组数据。事实上,若紫书上说的是错的,那么这道题就不可以用二分来解决。
自己思考了很久才得出的结论,不知道是不是对的,也可能是题目没读懂或者哪里想错了,希望能有大牛能指导一下。
AC代码
#include<bits/stdc++.h>
#define maxn 100010
#define maxm 200010
using namespace std;
struct node
{
int ls,rs;
bool ou;
}Node[maxm];
int n,m;
int root;
bool ans0,ansn;
bool run(int k)
{
for(int i=1;i<=m;i++)
{
int ls=Node[i].ls;
int rs=Node[i].rs;
bool ans1,ans2;
if(ls<0) ans1=-ls<=k;
else ans1=Node[ls].ou;
if(rs<0) ans2=-rs<=k;
else ans2=Node[rs].ou;
Node[i].ou=!(ans1&&ans2);
}
return Node[m].ou;
}
int lb(int x,int y)
{
while(x<y)
{
int m=x+(y-x)/2;
if(run(m)==ansn) y=m;
else x=m+1;
}
return x;
}
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
scanf("%d %d",&n,&m);
for(int i=1;i<=m;i++)
scanf("%d %d",&Node[i].ls,&Node[i].rs);
ans0=run(0);
ansn=run(n);
if(ans0==ansn)
{
for(int i=1;i<=n;i++) printf("0");
puts("");
}
else
{
int ANS=lb(1,n+1);
for(int i=1;i<ANS;i++) printf("1");
printf("x");
for(int i=ANS+1;i<=n;i++) printf("0");
puts("");
}
}
return 0;
}
这个WA了,不知道为啥= =
#include<bits/stdc++.h>
#define maxn 100010
#define maxm 200010
using namespace std;
struct node
{
int ls,rs;
bool ou;
}Node[maxm];
int n,m;
int root;
bool ans;
bool run(int k)
{
for(int i=1;i<=m;i++)
{
int ls=Node[i].ls;
int rs=Node[i].rs;
bool ans1,ans2;
if(ls<0) ans1=-ls<=k;
else ans1=Node[ls].ou;
if(rs<0) ans2=-rs<=k;
else ans2=Node[rs].ou;
Node[i].ou=!(ans1&&ans2);
}
return Node[m].ou;
}
int lb(int x,int y)
{
while(x<y)
{
int m=x+(y-x)/2;
if(run(m)==(ans^1)) y=m;
else x=m+1;
}
return x;
}
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
scanf("%d %d",&n,&m);
for(int i=1;i<=m;i++)
scanf("%d %d",&Node[i].ls,&Node[i].rs);
ans=run(0);
int ANS=lb(1,n+1);
if(ANS==n+1)
{
for(int i=1;i<=n;i++) printf("0");
puts("");
}
else
{
for(int i=1;i<ANS;i++) printf("1");
printf("x");
for(int i=ANS+1;i<=n;i++) printf("0");
puts("");
}
}
return 0;
}