D. Huge Strings Codeforces Round #438 by Sberbank and Barcelona Bootcamp (Div. 1 + Div. 2 combined)

http://codeforces.com/contest/868/problem/D

优化:两个串合并

原有状态+ 第一个串的尾部&第二个串的头部的状态

串变为第一个串的头部&第二个串的尾部

注意:

头尾不能重复

如串A合并串A

这就意味着串的头尾不能有重合,

详见代码

#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>
#include <time.h>
#include <string>
#include <set>
#include <map>
#include <list>
#include <stack>
#include <queue>
#include <vector>
#include <bitset>
#include <ext/rope>
#include <algorithm>
#include <iostream>
using namespace std;
#define ll long long
#define minv 1e-6
#define inf 1e9
#define pi 3.1415926536
#define E  2.7182818284
const ll mod=1e9+7;//998244353
const int maxn=201;

int w=15;

int f[maxn][1<<(15+1)]={0},add[15+2];
int len,value;
string str,s,pre[maxn],post[maxn];

void work(int index,string a)
{
    int i,j,z;
    len=a.length();
    for (j=1;j<=w;j++)
    {
        value=0;
        z=(1<<(j-1))-1;
        for (i=0;i<len;i++)
        {
            value=(value<<1|(a[i]=='1'));
            if (i>=j-1)
            {
                f[index][value+add[j]]=1;
                value=value&z;
            }
        }
    }
}

int main()
{
    int n,q,Q,x,y,i;
    add[1]=0;
    for (i=2;i<=w+1;i++)
        add[i]=(1<<i)-2;

    scanf("%d",&n);
    for (i=1;i<=n;i++)
    {
        cin>>str;
        work(i,str);
        len=str.size();
        if (len<=w)
            pre[i]=str;
        else
        {
            pre[i]=str.substr(0,w);
            if (len>=w+w)
                post[i]=str.substr(str.length()-w,w);
            else
                post[i]=str.substr(str.length()-len+w,len-w);
        }
    }

    scanf("%d",&q);
    for (Q=n+1;Q<=n+q;Q++)
    {
        scanf("%d%d",&x,&y);

        for (i=0;i<add[w+1];i++)
            f[Q][i]=f[x][i] | f[y][i];

        if (post[x].empty())
            str=pre[x];
        else if (post[x].length()<w)
            str=pre[x].substr(pre[x].length()-(w-post[x].length()),w-post[x].length())+post[x];
        else
            str=post[x];
        str+=pre[y];

        work(Q,str);

        str=pre[x]+post[x]+pre[y]+post[y];
        pre[Q]=str.substr(0,min(w,(int)str.length()));
        str.erase(0,min(w,(int)str.length()));
        post[Q]=str.substr(str.length()-min(w,(int)str.length()),min(w,(int)str.length()));

        for (i=0;i<add[w+1];i++)
            if (f[Q][i]==0)
                break;
        printf("%d
",(int)(log(2+i+minv)/log(2))-1);
    }
    return 0;
}
原文地址:https://www.cnblogs.com/cmyg/p/9520984.html