Boboniu and String

Boboniu defines BN-string as a string s of characters ‘B’ and ‘N’.

You can perform the following operations on the BN-string s:

  • Remove a character of s.
  • Remove a substring “BN” or “NB” of s.
  • Add a character ‘B’ or ‘N’ to the end of s.
  • Add a string “BN” or “NB” to the end of s.

Note that a string a a a is a substring of a string b b b if a can be obtained from b b b by deletion of several (possibly, zero or all) characters from the beginning and several (possibly, zero or all) characters from the end.

Boboniu thinks that BN-strings s s s and t t t are s i m i l a r similar similar if and only if:

  • ∣ s ∣ = ∣ t ∣ |s|=|t| s=t.
  • There exists a permutation p 1 , p 2 , … , p ∣ s ∣ p_1,p_2,…,p_{|s|} p1,p2,,ps such that for all i i i ( 1 ≤ i ≤ ∣ s ∣ ) (1≤i≤|s|) (1is), s p i = t i s_{p_i}=t_i spi=ti.

Boboniu also defines d i s t ( s , t ) dist(s,t) dist(s,t), the distance between s s s and t t t, as the minimum number of operations that makes s s s similar to t t t.

Now Boboniu gives you n n n non-empty BN-strings s 1 , s 2 , … , s n s_1,s_2,…,s_n s1,s2,,sn and asks you to find a non-empty BN-string t t t such that the maximum distance to string s s s is minimized, i.e. you need to minimize max ⁡ i = 1 n d i s t ( s i , t ) \max _{i=1}^ndist(s_i,t) maxi=1ndist(si,t).

Input
The first line contains a single integer n n n ( 1 ≤ n ≤ 3 ⋅ 1 0 5 ) (1≤n≤3⋅10^5) (1n3105).

Each of the next n n n lines contains a string s i s_i si ( 1 ≤ ∣ s i ∣ ≤ 5 ⋅ 1 0 5 ) (1≤|s_i|≤5⋅10^5) (1si5105). It is guaranteed that s i s_i si only contains ‘B’ and ‘N’. The sum of ∣ s i ∣ |s_i| si does not exceed 5 ⋅ 1 0 5 5⋅10^5 5105.

Output
In the first line, print the minimum m a x i = 1 n d i s t ( s i , t ) max_{i=1}^ndist(s_i,t) maxi=1ndist(si,t).

In the second line, print the suitable t t t.

If there are several possible t t t's, you can print any.

Examples

input
3
B
N
BN
output
1
BN
input
10
N
BBBBBB
BNNNBBNBB
NNNNBNBNNBNNNBBN
NBNBN
NNNNNN
BNBNBNBBBBNNNNBBBBNNBBNBNBBNBBBBBBBB
NNNNBN
NBBBBBBBB
NNNNNN
output
12
BBBBBBBBBBBBNNNNNNNNNNNN
input
8
NNN
NNN
BBNNBBBN
NNNBNN
B
NNN
NNNNBNN
NNNNNNNNNNNNNNNBNNNNNNNBNB
output
12
BBBBNNNNNNNNNNNN
input
3
BNNNBNNNNBNBBNNNBBNNNNBBBBNNBBBBBBNBBBBBNBBBNNBBBNBNBBBN
BBBNBBBBNNNNNBBNBBBNNNBB
BBBBBBBBBBBBBBNBBBBBNBBBBBNBBBBNB
output
12
BBBBBBBBBBBBBBBBBBBBBBBBBBNNNNNNNNNNNN

Note
In the first example d i s t ( B , B N ) = d i s t ( N , B N ) = 1 , d i s t ( B N , B N ) = 0 dist(B,BN)=dist(N,BN)=1, dist(BN,BN)=0 dist(B,BN)=dist(N,BN)=1,dist(BN,BN)=0. So the maximum distance is 1 1 1.

由于不考虑字符串中字符的排列顺序,因此如果分别把字符串中’N’的个数和’B’的个数看做是坐标轴上的横纵坐标,那么每一个字符串都可以在坐标系上表示出来。同样,相关操作也可以表示成向量。
Boboniu and String_第1张图片
如果对一个串进行 x x x次操作,则可以用扩大了 x x x倍的六边形表示。

因为六边形中中心点到边缘的操作数中到六个顶点所需的操作数是最少的,而如果两个同样大小的六边形面积相交,则一个六边形的一个顶点一定在另一个六边形边缘或内部,因此只有两个点操作数为 x x x对应的六边形相交,才能确定两个串距离至多为 x x x
由于答案具有单调性,因此可以通过二分距离得到答案。
假设当前距离为 m m m。如果所有六边形有共同的区域,则这块区域的底部纵坐标 y m i n = max ⁡ i = 1 n y i − m y_{min}=\max\limits_{i=1}^ny_i-m ymin=i=1maxnyim;顶部纵坐标 y m a x = min ⁡ i = 1 n y i + m y_{max}=\min\limits_{i=1}^ny_i+m ymax=i=1minnyi+m;左边横坐标 x m i n = max ⁡ i = 1 n x i − m x_{min}=\max\limits_{i=1}^nx_i-m xmin=i=1maxnxim;右边横坐标 x m a x = min ⁡ i = 1 n x i + m x_{max}=\min\limits_{i=1}^nx_i+m xmax=i=1minnxi+m;斜边缘截距最小值 b m i n = max ⁡ i − 1 n ( y i − x i ) − m b_{min}=\max\limits_{i-1}^n(y_i-x_i)-m bmin=i1maxn(yixi)m;斜边缘截距最大值 b m a x = min ⁡ i − 1 n ( y i − x i ) + m b_{max}=\min\limits_{i-1}^n(y_i-x_i)+m bmax=i1minn(yixi)+m
显然如果 y m i n > y m a x y_{min}>y_{max} ymin>ymax x m i n > x m a x x_{min}>x_{max} xmin>xmax d m i n > d m a x d_{min}>d_{max} dmin>dmax,则不存在公共区域。
如果 x x x y y y限制条件构成的矩形与两斜线之间的区域不相交,即 y m i n − x m a x > b m a x y_{min}-x_{max}>b_{max} yminxmax>bmax y m a x − x m i n > b m i n y_{max}-x_{min}>b_{min} ymaxxmin>bmin,同样不存在相交区域。
如果相交区域存在,则讨论两斜线与矩形的关系找到公共区域中的一个点。注意,由于 t t t不能是空串,因此得到的坐标值应尽可能大。因此要找矩形右边缘或上边缘与斜线的交点或矩形右上角。

#include

#define si(a) scanf("%d",&a)
#define sl(a) scanf("%lld",&a)
#define sd(a) scanf("%lf",&a)
#define sc(a) scahf("%c",&a);
#define ss(a) scanf("%s",a)
#define pi(a) printf("%d\n",a)
#define pl(a) printf("%lld\n",a)
#define pc(a) putchar(a)
#define ms(a) memset(a,0,sizeof(a))
#define repi(i, a, b) for(register int i=a;i<=b;++i)
#define repd(i, a, b) for(register int i=a;i>=b;--i)
#define reps(s) for(register int i=head[s];i;i=Next[i])
#define ll long long
#define ull unsigned long long
#define vi vector
#define pii pair
#define mii unordered_map
#define msi unordered_map
#define lowbit(x) ((x)&(-(x)))
#define ce(i, r) i==r?'\n':' '
#define pb push_back
#define fi first
#define se second
#define all(x) x.begin(),x.end()
#define INF 0x3f3f3f3f
#define pr(x) cout<<#x<<": "<
using namespace std;

inline int qr() {
    int f = 0, fu = 1;
    char c = getchar();
    while (c < '0' || c > '9') {
        if (c == '-')fu = -1;
        c = getchar();
    }
    while (c >= '0' && c <= '9') {
        f = (f << 3) + (f << 1) + c - 48;
        c = getchar();
    }
    return f * fu;
}

const int N = 5e5 + 10;
char s[N];
int n;
int maxa, mina = INF, maxb, minb = INF, mxd = -INF, mnd = INF;

inline pii check(int x) {
    int minx = max(0, maxa - x), maxx = mina + x, miny = max(0, maxb - x), maxy = minb + x, mind = mxd - x, maxd = mnd + x;
    if (minx > maxx || miny > maxy || mind > maxd || miny - maxx > maxd || maxy - minx < mind)return {-1, -1};
    if (maxd >= maxy - minx && mind <= miny - maxx)return {maxx, maxy};
    if (maxd <= maxy - maxx)return {maxx, maxx + maxd};
    if (maxd <= maxy - minx)return {maxy - maxd, maxy};
    if (mind >= maxy - maxx)return {maxy - mind, maxy};
    if (mind >= miny - maxx)return {maxx, maxx + mind};
}

int main() {
    n = qr();
    repi(i, 1, n) {
        ss(s + 1);
        int l = strlen(s + 1);
        int a = count(s + 1, s + 1 + l, 'N'), b = l - a;
        mina = min(mina, a), maxa = max(maxa, a);
        minb = min(minb, b), maxb = max(maxb, b);
        mnd = min(mnd, b - a), mxd = max(mxd, b - a);
    }
    int l = 0, r = 2e5;
    while (l < r) {
        int mid = (l + r) >> 1;
        check(mid).fi == -1 ? (l = mid + 1) : (r = mid);
    }
    pi(l);
    pii ans = check(l);
    repi(i, 1, ans.fi)pc('N');
    repi(i, 1, ans.se)pc('B');
    return 0;
}

你可能感兴趣的:(ACM,思维,二分)