AGC026E - Synchronized Subsequence

AGC026E - Synchronized Subsequence

題目描述

Solution

定義cnt[x][0],cnt[x][1]cnt[x][0],cnt[x][1]表示在前xx個數中0的個數和1的個數分別是多少。

然後把整個串ss劃分爲若干個子串,劃分點在所有cnt[i][0]=cnt[i][1]cnt[i][0]=cnt[i][1]的位置ii,顯然這樣劃分,不同的子串之間互不影響,最後合併所有子串(pick    or    banpick\;\;or\;\;ban)就是最終答案了。

顯然這樣劃分子串之後,可以把子串分爲兩類:
1.a的前綴個數始終大於b,例如:aababb。
2.a的前綴個數始終小於b,例如:bbbaabaa。

對於第一類,字典序最大的方案即爲若干個ab拼接,例如:aababb最優選擇是abab。
對於第二類,答案一定是它的一個後綴。

所以對於每一個子串,我們可以在O(n2)O(n^2)的時間內求出答案。

然後我們考慮合併答案,直接dpdp計算即可(我用錯誤的排序+特判卡過去了hhhhhh)。

總時間複雜度O(n2)O(n^2)

以下是錯誤的程序:

#include <vector>
#include <list>
#include <map>
#include <set>
#include <deque>
#include <queue>
#include <stack>
#include <bitset>
#include <algorithm>
#include <functional>
#include <numeric>
#include <utility>
#include <sstream>
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <cctype>
#include <string>
#include <cstring>
#include <ctime>
#include <cassert>
#include <string.h>
//#include <unordered_set>
//#include <unordered_map>
//#include <bits/stdc++.h>

#define MP(A,B) make_pair(A,B)
#define PB(A) push_back(A)
#define SIZE(A) ((int)A.size())
#define LEN(A) ((int)A.length())
#define FOR(i,a,b) for(int i=(a);i<(b);++i)
#define fi first
#define se second

using namespace std;

template<typename T>inline bool upmin(T &x,T y) { return y<x?x=y,1:0; }
template<typename T>inline bool upmax(T &x,T y) { return x<y?x=y,1:0; }

typedef long long ll;
typedef unsigned long long ull;
typedef long double lod;
typedef pair<int,int> PR;
typedef vector<int> VI;

const lod eps=1e-11;
const lod pi=acos(-1);
const int oo=1<<30;
const ll loo=1ll<<62;
const int mods=998244353;
const int MAXN=6005;
const int INF=0x3f3f3f3f;//1061109567
/*--------------------------------------------------------------------*/
inline int read()
{
	int f=1,x=0; char c=getchar();
	while (c<'0'||c>'9') { if (c=='-') f=-1; c=getchar(); }
	while (c>='0'&&c<='9') { x=(x<<3)+(x<<1)+(c^48); c=getchar(); }
	return x*f;
}
char ST[MAXN>>1][MAXN],st[MAXN],ch[MAXN];
int c[MAXN],ID[MAXN],id[MAXN],cnt[2];
PR p[MAXN];
int compare(char *x,char *y)
{
	
	int lenx=strlen(x+1),leny=strlen(y+1),ans=0; 
	bool flag=1;
	for (int i=3;i<=lenx;i++)
		if (x[i]!=x[i-2]) { flag=0; break; }
	for (int i=3;i<=leny;i++)
		if (y[i]!=y[i-2]) { flag=0; break; }
	if (flag)
	{
		if (x[1]==y[1]&&x[2]==y[2]) return 2;
	}
	
	int len=max(lenx,leny);
	for (int i=1;i<=len;i++)
		if (x[i]>y[i]) return ans^1;
		else if (x[i]<y[i]) return ans;
	return 2;
}

int compare(char *x,char *y,int len)
{
	for (int i=1;i<=len;i++)
		if (x[i]>y[i]) return 1;
		else if (x[i]<y[i]) return 0;
	return 2;
}
int comparec(int x,int y){ return x>y; } 
void solve(int t,int l,int r)
{
	if (st[l]=='a')
	{
		int mx=0;
		for (int i=l;i<=r;i++)
		if (st[i]=='a')
		{
			int tmp=0;
			for (int j=i;j<=r;j++)
				if (st[j]=='a') ++tmp,j=p[id[j]].se;
			upmax(mx,tmp);
		}
		for (int i=1;i<=mx<<1;i+=2) ST[t][i]='a',ST[t][i+1]='b';
	}
	if (st[l]=='b')
	{
		int num=0;
		for (int i=l;i<=r;i++) if (st[i]=='a') c[++num]=id[i];
		sort(c+1,c+num+1,comparec);
		for (int i=1;i<=r-l+1;i++) ST[t][i]=st[i+l-1];
		for (int i=1;i<=num;i++)
		{
			int len=0;
			for (int j=l;j<=r;j++)
				if (id[j]>=c[i]) ch[++len]=st[j];
//			cout<<ch+1<<endl;
			if (compare(ch,ST[t],len)==1)
			{
				for (int j=1;j<=len;j++) ST[t][j]=ch[j];
				for (int j=len+1;j<=r-l+1;j++) ST[t][j]=NULL;
			}
		}
	}
//	cout<<ST[t]+1<<endl;
}
int compareid(int x,int y) { int t=compare(ST[x],ST[y]); return (t==1||t==2&&x<y); } 
int main()
{
//	freopen("a.in","r",stdin);
//	freopen("a.out","w",stdout);
	int n=read();
	scanf("%s",st+1);
	int numa=0,numb=0;
	for (int i=1;i<=n<<1;i++)
	{
		if (st[i]=='a') p[++numa].fi=i,id[i]=numa;
		if (st[i]=='b') p[++numb].se=i,id[i]=numb;
	}
	
	int t=0;
	for (int i=1,lst=1;i<=n<<1;i++)
	{
		cnt[st[i]-'a']++;
		if (cnt[0]==cnt[1]) ID[++t]=t,solve(t,lst,i),lst=i+1;
	}
	sort(ID+1,ID+t+1,compareid);
//	cout<<endl;
//	for (int i=1;i<=t;i++) cout<<ST[i]+1<<" "<<ID[i]<<endl;
	int smax=0;
	for (int i=1;i<=t;i++)
		if (ID[i]>smax) printf("%s",ST[ID[i]]+1),smax=ID[i]; 
	return 0;
}
/*
10
ba ab ba ba bbabbbaaaa ab

20
ba ab bbabaa bbbabbabbabbaaaaaa aabb aabababb
*/ 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章