计蒜客 字符串条件

来源:互联网 发布:牛耳软件学院图片 编辑:程序博客网 时间:2024/05/21 22:40

通过O(n)处理next数组,可以得到一些诸如Si=SjSiSj的式子,将所有相等的位置都连通起来。之后为所有不等号连边,问题变成用16个颜色在这个图上染色,且点编号越小,颜色值越小。O(n)贪心即可。

#include<algorithm>#include<iostream>#include<cstring>#include<cstdio>#include<string>#include<cmath>using namespace std;#define clr(a) memset(a,0,sizeof(a))//--Container#include<vector>//typedef long long ll;typedef unsigned long long ull;struct eg{int u,v,nx;}gp[200010];int ar[100010],ct[100010],bi[100010][2],hd[100010],rs[100010],cnt,bn,sm,n;char cz[100010];int fi(int a){return ct[a]==a?a:ct[a]=fi(ct[a]);};void psh(int u,int v){++cnt;gp[cnt].u=u,gp[cnt].v=v,gp[cnt].nx=hd[u],hd[u]=cnt;};bool _cl(){    int i,j;bool bd[16];if(ar[1])return 0;    if(n==1){cz[1]='a';return 1;}    for(i=1;i<=n;++i)ct[i]=i;    for(bn=0,i=2;i<=n;++i){        for(j=ar[i-1];j&&j+1!=ar[i];j=ar[j]){bi[bn][0]=j+1,bi[bn][1]=i;++bn;}        if(!ar[i]){bi[bn][0]=1,bi[bn][1]=i;++bn;continue;}        if(ar[i]!=j+1)return 0;        ct[i]=fi(j+1);    }    for(cnt=0,clr(hd),i=0;i<bn;++i){        bi[i][0]=fi(bi[i][0]),bi[i][1]=fi(bi[i][1]);        if(bi[i][0]==bi[i][1])return 0;        psh(bi[i][0],bi[i][1]),psh(bi[i][1],bi[i][0]);    }    for(clr(rs),i=1;i<=n;++i){        for(clr(bd),j=hd[i];j;j=gp[j].nx)bd[rs[gp[j].v]]=1;        for(j=1;j<=16&&bd[j];++j);        if(j>16)return 0;        rs[i]=j;    }    for(i=1;i<=n;++i)cz[i]=rs[fi(i)]+'a'-1;    return 1;};void cl(){    int i,j,k,t,a,b;scanf("%d",&n);    for(clr(cz),clr(ar),i=1;i<=n;scanf("%d",&ar[i++]));    if(!_cl())printf("-1\n");    else        printf("%s\n",cz+1);};int main() {#ifndef ONLINE_JUDGE    freopen("in.txt","r",stdin);    freopen("out.txt","w",stdout);#endif    cl();    return 0;};
原创粉丝点击