【CodeForces】708 B. Recover the String 数学构造

时间:2023-03-08 17:37:51

【题目】B. Recover the String

【题意】找到一个串s,满足其中子序列{0,0}{0,1}{1,0}{1,1}的数量分别满足给定的数a1~a4,或判断不存在。数字<=10^9,答案<=10^6。

【算法】数学构造

【题解】首先由a1和a4易得0的数量x0和1的数量x1。

容易发现01和10关系密切,令1的位置为b1...bx1,则:

{0,1} (b1-1)+(b2-2)+(b3-3)+...+(bx1-x1)=a2

{1,0} (x0-b1+1)+(x0-b2+1)+...+(x0-bx1+x1)=a3

两式相加,得x0*x1=a2+a3。

因此,只要满足表达式x0*x1=a2+a3,串就一定存在,此时只要随便构造b[]使得{0,1}数量符合,那么{1,0}数量就一定随之符合。

注意特殊处理0的情况。

#include<cstdio>
#include<cstring>
#include<cctype>
#include<cmath>
#include<queue>
#include<stack>
#include<set>
#include<vector>
#include<algorithm>
#define ll long long
#define lowbit(x) x&-x
using namespace std;
int read(){
char c;int s=,t=;
while(!isdigit(c=getchar()))if(c=='-')t=-;
do{s=s*+c-'';}while(isdigit(c=getchar()));
return s*t;
}
int min(int a,int b){return a<b?a:b;}
int max(int a,int b){return a<b?b:a;}
int ab(int x){return x>?x:-x;}
//int MO(int x){return x>=MOD?x-MOD:x;}
//void insert(int u,int v){tot++;e[tot].v=v;e[tot].from=first[u];first[u]=tot;}
/*------------------------------------------------------------*/
const int inf=0x3f3f3f3f; int n,a1,a2,a3,a4,x0,x1,b[],c[];
void p(){printf("Impossible");exit();}
int main(){
scanf("%d%d%d%d",&a1,&a2,&a3,&a4);
for(int i=;i>=;i--){
if(1ll*i*(i-)/==a1)x0=i;
if(1ll*i*(i-)/==a4)x1=i;
}
if(!x0||!x1)p();
if(a2+a3==){
if(x0==){
for(int i=;i<=x1;i++)printf("");
return ;
}
if(x1==){
for(int i=;i<=x0;i++)printf("");
return ;
}
}
if(x0*x1!=a2+a3)p();
for(int i=;i<=x1;i++)b[i]=i;
for(int i=x1;i>=;i--){
if(a2>x0)b[i]=x0+i,a2-=x0;else{b[i]=a2+i;break;}
}
for(int i=;i<=x1;i++)c[b[i]]=;
for(int i=;i<=x1+x0;i++)printf("%d",c[i]);
return ;
}