D
超级无敌的分类讨论
题目大意
试构造一个串 aij 为串中的ij序列的个数
厉害就厉害在这个处理上
先判断各种无解
然后
先试着能不能放0
放0的条件是
1、 (dq0+1)∗(one−dq1)+dq01<=a01
放完之后的维护是
2、 dq0=dq0+1,dq10=dq10+dq1
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;
const int MAXN = 1000000 + 5;
const int MAXL = 1000000;
bool num[MAXN];
int n;
int a00,a01,a10,a11;
int zero,one;
int main()
{
scanf("%d %d %d %d",&a00,&a01,&a10,&a11);
if(!a00 && !a01 && !a10 && !a11)
{
puts("0");
return 0;
}
for(zero = 0;zero <= MAXL + 1;zero ++)
if(zero * (zero - 1) == a00 * 2)
break;
for(one = 0;one <= MAXL + 1;one ++)
if(one * (one - 1) == a11 * 2)
break;
if(!zero && (a01 || a10))
zero++;
if(!one && (a01 || a10))one++;
if(zero + one > MAXL)
{
puts("Impossible");
return 0;
}
n = zero + one;
int dq0 = 0,dq1 = 0;
int dq01 = 0,dq10 = 0;
for(int i = 1;i <= n;i ++)
{
if((dq0 + 1) * (one - dq1) + dq01 <= a01)
{
num[i] = 0;
dq0 ++;
dq10 += dq1;
continue;
}
else
{
num[i] = 1;
dq1 ++;
dq01 += dq0;
continue;
}
}
if(dq01 != a01 || dq10 != a10)
{
puts("Impossible");
return 0;
}
for(int i = 1;i <= n;i ++)
printf("%d",num[i]);
puts("");
return 0;
}