luogu P3234 [HNOI2014]抄卡组

传送门

nmdwsm

自己看吧,不想写了qwq

垃圾代码如下 和题解完全不一样

#define LL long long
#define uLL unsigned long long
#define il inline
#define re register

using namespace std;
const int M=1e7+10,N=1e5+10;
il int rd()
{
    int x=0,w=1;char ch=0;
    while(ch<'0'||ch>'9') {if(ch=='-') w=-1;ch=getchar();}
    while(ch>='0'&&ch<='9') {x=(x<<3)+(x<<1)+(ch^48);ch=getchar();}
    return x*w;
}
uLL hb[M],bb[M],bs=2333;
vector<char> cc[N];
int l[N],r[N],s[N];
bool v[N];
string fk;

int main()
{
    freopen("3574.in","r",stdin);
    freopen("3574.out","w",stdout);
	bb[0]=1;
	for(int i=1;i<M-1;++i) bb[i]=bb[i-1]*bs;
	int T=rd();
	while(T--)
	{
		int n=rd();
		for(int i=0;i<=n;++i) v[i]=0;
		int m=0;
		char ch;
		/*while(233)
		{
			ch=getchar();
			if(ch=='\n'||ch==-1)
			{
				++m;
				if(m>=n) break;
				l[m]=0,r[m]=-1,cc[m].clear();
			}
			else ++r[m],cc[m].push_back(ch);
		}*/
		for(int i=0;i<n;++i)
		{
			l[i]=0,cc[i].clear();
			cin>>fk;
			//int nmd=((int)fk.length())-1;
			r[i]=((int)fk.length())-1;
			for(int j=l[i];j<=r[i];++j) cc[i].push_back(fk[j]);
		}
		m=n;
		while(233)
		{
			int i=0;
			ch=0;
			while(i<m)
			{
				int j=i;
				if(l[j]>r[j]) break;
				if(cc[j][l[j]]=='*') break;
				if(!ch||ch==cc[j][l[j]]) ch=cc[j][l[j]];
				else break;
				++i;
			}
			if(i<m||!ch) break;
			for(int j=0;j<m;++j) ++l[j];
		}
		while(233)
		{
			int i=0;
			ch=0;
			while(i<m)
			{
				int j=i;
				if(l[j]>r[j]) break;
				if(cc[j][r[j]]=='*') break;
				if(!ch||ch==cc[j][r[j]]) ch=cc[j][r[j]];
				else break;
				++i;
			}
			if(i<m||!ch) break;
			for(int j=0;j<m;++j) --r[j];
		}
		uLL ha=0;
		int h=0,px=0,py=1;
		while(h<n)
		{
			uLL hh=0;
			bool o=0;
			for(int i=l[h];i<=r[h];++i)
			{
				if(cc[h][i]!='*') hh=hh*bs+cc[h][i];
				else o=1;
			}
			if(o) {++h;continue;}
			v[h]=1;
			if(!px||ha==hh) px=1,ha=hh;
			else py=0;
			++h;
		}
		if(!py) {puts("N");continue;}
		if(px)
		{
			int i,ma=0;
			for(i=0;i<n;++i)
				if(v[i]) {swap(cc[i],cc[0]),swap(v[i],v[0]),swap(l[i],l[0]),swap(r[i],r[0]);break;}
			for(i=0;i<n;++i) ma=max(ma,r[i]);
			hb[0]=cc[0][0];
			for(i=1;i<=r[0];++i) hb[i]=hb[i-1]*bs+cc[0][i];
			for(i=r[0]+1;i<=ma;++i) hb[i]=0;
			for(i=1;i<n;++i)
			{
				if(v[i]) continue;
				ha=0;
				int j=l[0],k=r[0],ll=0;
				while(l[i]<=r[i]&&j<=k&&cc[i][l[i]]==cc[0][j]) ++l[i],++j;
				while(l[i]<=r[i]&&j<=k&&cc[i][r[i]]==cc[0][k]) --r[i],--k;
				if(l[i]<=r[i]&&(cc[i][l[i]]!='*'||cc[i][r[i]]!='*')) break;
				while(l[i]<=r[i]&&j<=k)
				{
					if(cc[i][l[i]]!='*') ++ll,++j,ha=ha*bs+cc[i][l[i]];
					else
					{
						if(ll)
						{
							while(j<=k&&ha!=hb[j]-hb[j-ll]*bb[ll]) ++j;
							if(j>k) l[i]=-233;
						}
						ll=0,ha=0;
					}
					++l[i];
				}
				while(l[i]>=0&&l[i]<=r[i]&&cc[i][l[i]]=='*') ++l[i];
				if(l[i]<=r[i]) break;
			}
			puts(i>=n?"Y":"N");
			continue;
		}
		for(int i=0;i<n;++i) s[i]=i;
		m=n;
		while(233)
		{
			int i=0;
			ch=0;
			while(i<m)
			{
				int j=s[i];
				if(l[j]>r[j]) break;
				if(cc[j][l[j]]=='*') swap(s[i],s[m-1]),--m,--i;
				else if(!ch||ch==cc[j][l[j]]) ch=cc[j][l[j]];
				else break;
				++i;
			}
			if(i<m||!ch) break;
			for(int j=0;j<m;++j) ++l[s[j]];
		}
		for(int i=0;i<n;++i) s[i]=i;
		m=n;
		while(233)
		{
			int i=0;
			ch=0;
			while(i<m)
			{
				int j=s[i];
				if(l[j]>r[j]) break;
				if(cc[j][r[j]]=='*') swap(s[i],s[m-1]),--m,--i;
				else if(!ch||ch==cc[j][r[j]]) ch=cc[j][r[j]];
				else break;
				++i;
			}
			if(i<m||!ch) break;
			for(int j=0;j<m;++j) --r[s[j]];
		}
		int c1=0,c2=0;
		for(int i=0;i<n;++i) c1+=l[i]>r[i]||v[i],c2+=l[i]<=r[i]&&cc[i][l[i]]=='*'&&cc[i][r[i]]=='*';
		puts(c1==n||c2==n?"Y":"N");
	}
	return 0;
}

md我是真的\(**\),分类讨论没考虑完全,数组开小,局部变量开的过大,没清空数组,没考虑空行,然后写了一万年,,,

8说了

posted @ 2019-02-21 15:42  ✡smy✡  阅读(244)  评论(0编辑  收藏  举报