AGC026E - Synchronized Subsequence
题目描述
Solution
定义 表示在前 个数中0的个数和1的个数分别是多少。
然后把整个串 划分为若干个子串,划分点在所有 的位置 ,显然这样划分,不同的子串之间互不影响,最后合并所有子串( )就是最终答案了。
显然这样划分子串之后,可以把子串分为两类:
1.a的前缀个数始终大于b,例如:aababb。
2.a的前缀个数始终小于b,例如:bbbaabaa。
对于第一类,字典序最大的方案即为若干个ab拼接,例如:aababb最优选择是abab。
对于第二类,答案一定是它的一个后缀。
所以对于每一个子串,我们可以在 的时间内求出答案。
然后我们考虑合并答案,直接 计算即可(我用错误的排序+特判卡过去了 )。
总时间复杂度 。
以下是错误的程序:
#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
*/