# In short, it is the solution of | CSP-S2 2021 (part)

Sync published on hriver2.github.io

# "Start"

Because I felt very unwilling on the field, I wrote out the first three questions I had seen on the field.

T4 didn't write because I didn't think it was within my ability(

But on the whole, this year's questions seem simpler than last year, and the difficult ones are also simpler than last year, but the overall difficulty seems a little harder. In addition, the violence score is less than last year, so the score line is lower (?)

Anyway, I had no idea about the greedy snake last year. I still have some ideas about T4 this year(

The following codes are used Default source V5.2.

# 「A」 Corridor bridge distribution

Generally speaking, this problem is really not difficult. His practice and positive solution on the field are only a circular difference, but he didn't continue to think about this problem just because he wanted to beat all the violence he could fight first.

When I wanted to write this, I thought I should test the official data. Unexpectedly \ (A \) hung up first, so I repaired the code style again when I changed it.

## 「A」 Brief description of ideas

The first is the violent practice of \ (O(n^2\log n) \) on the field.

The idea is very simple. First sort, then enumerate the allocated time, and then enumerate the aircraft inside. Each time, eject the aircraft that should fly away from the pile, and then stop the current aircraft at the corridor bridge with the smallest number.

The examination room code is too ugly. I'm too lazy to fix it.

But this obviously can't pass, so we consider optimization. The first thing we can think of is that such greed is absolutely no problem, so we consider how to reduce the complexity of the process.

After careful analysis, in fact, we can separate the two aircraft for preprocessing, and finally merge the corresponding answers. Therefore, we need to deal with the scheme of allocating \ (0 \) to \ (n \) corridor bridges for each aircraft. In order to optimize the complexity, we must not be silly.

According to our greedy strategy just now, we have to find the corridor bridge with the smallest number and put it in every time we release the aircraft, so we can throw the number of the available corridor bridge into a small root pile, and then throw it into another pile together with the aircraft occupying the corridor bridge every time it is used, so that our processing complexity is reduced to \ (O(n \log n). \)

## 「A」Code

template<typename J>
I J Hmax(const J &x,const J &y)
{
Heriko x>y?x:y;
}

template<typename J>
I J Hmin(const J &x,const J &y)
{
Heriko x<y?x:y;
}

CI MXX(1e5+1);

int n,m1,m2,coa[MXX],cob[MXX],ans;

struct Plane
{
int l,r;

I bool operator < (const Plane &co) const
{
Heriko (l==co.l)?(r<co.r):(l<co.l);
}
}

a1[MXX],a2[MXX];

priority_queue<int> id;

priority_queue< pair<int,int> > q;

S main()
{
Files();

fr(n),fr(m1),fr(m2);

for(int i(1);i<=m1;++i)
fr(a1[i].l),fr(a1[i].r);

for(int i(1);i<=m2;++i)
fr(a2[i].l),fr(a2[i].r);

sort(a1+1,a1+1+m1);
sort(a2+1,a2+1+m2);

for(int i(1);i<=n;++i)
id.push(-i);

for(int i(1);i<=m1;++i)
{
while(q.size() and -q.top().first<a1[i].l)
id.push(-q.top().second),q.pop();

if(id.size())
{
q.push(make_pair(-a1[i].r,-id.top()));
++coa[-id.top()];id.pop();
}
}

for(int i(1);i<=n;++i)
coa[i]+=coa[i-1];

while(id.size())
id.pop();

while(q.size())
q.pop();

for(int i(1);i<=n;++i)
id.push(-i);

for(int i(1);i<=m2;++i)
{
while(q.size() and -q.top().first<a2[i].l)
id.push(-q.top().second),q.pop();

if(id.size())
{
q.push(make_pair(-a2[i].r,-id.top()));
++cob[-id.top()];id.pop();
}
}

for(int i(1);i<=n;++i)
cob[i]+=cob[i-1];

for(int i(0);i<=n;++i)
ans=Hmax(ans,coa[i]+cob[n-i]);

fw(ans,1);

Heriko Deltana;
}


# 「B」 Bracket sequence

I felt it was a disgusting question. Then I wrote it for three hours and hung up. Finally, I hung up the violence. Then I submitted the sample and returned it to CE, Bad

## 「B」 Brief description of ideas

Let's not talk about violence. The following content is mainly for reference I_am_Accepted.

After seeing the data range, we have a more conventional complexity in mind: \ (O(n^3) \), which is a relatively normal complexity of interval DP, so we set the state and transition normally first.

Let \ (f(l,r) \) indicate that \ ([l,r] \) is a legal sequence and that \ (L \) and \ (r \) match, and \ (g(l,r) \) indicate the number of mismatches, so as to avoid repeated calculation. The final answer is obviously \ (f(1,n)+g(1,n) \). At the same time, because we have at most \ (k \) *, we can preprocess it at the initial time of \ (O(n^2) \) for later convenience.

Before the transfer, some states need to be judged:

• Skip when the end point is an undetermined symbol and cannot become a bracket;

• When the length of the current interval is \ (2 \), \ (f(l,r)=1 \), skip.

Then there is the transfer, first \ (f: \)

• $$(S): f(l,r)+=[co(l+1,r)].$$

• $$(A): f(l,r)+=f(l+1,r-1)+g(l+1,r-1).$$

• $$(SA): f(l,r)+=\sum_{i=1}^k(f(l+i+1,r-1)+g(l+i+1,r-1))\times[co(l+1,l+i)].$$

• $$(AS): f(l,r)+=\sum_{i=1}^k(f(l+1,r-i-1)+g(l+1,r-i-1))\times[co(r-i,r-1)].$$

Then \ (g: \)

• $$ASB / AB: g(l,r)+=\sum\limits_{l<i<j<r,j-i-1\le k}(f(l,i)+g(l,i)\times f(i,r))[co(i+1,j-1)].$$

However, this transfer is \ (O(n^4) \), so considering the complexity of optimizing this, it is found that each time \ (i \) increases or decreases \ (1 \), the change of \ (j \) is \ (O(1) \), which is controllable, so we can preprocess the next legal transfer object, and then optimize it to \ (O(n^2+n^3)=O(n^3). \)

## 「B」Code

template<typename J>
I J Hmax(const J &x,const J &y)
{
Heriko x>y?x:y;
}

template<typename J>
I J Hmin(const J &x,const J &y)
{
Heriko x<y?x:y;
}

CI MXX(501),MOD(1e9+7);

int n,k,nex[MXX];

LL f[MXX][MXX],g[MXX][MXX];

bitset<MXX> co[MXX];

char s[MXX];

S main()
{
Files();

fr(n),fr(k);
scanf("%s",s+1);

for(int i(1);i<=n;++i)
{
if(s[i]!='*' and s[i]!='?')
continue;

co[i][i]=1;

for(int j(i+1);j<=n;++j)
if(s[j]=='*' or s[j]=='?')
co[i][j]=1;
else
break;
}

for(int len(2);len<=n;++len)
{
for(int l(1),r;l<=n-len+1;++l)
{
r=len+l-1;f[l][r]=g[l][r]=0;

if((s[l]!='(' and s[l]!='?') or (s[r]!=')' and s[r]!='?'))
continue;

if(l+1==r)
{
(f[l][r]+=1)%=MOD;

continue;
}

/*----F----*/

if(r-l-1<=k and co[l+1][r-1])
(f[l][r]+=1)%=MOD;

(f[l][r]+=f[l+1][r-1]+g[l+1][r-1])%=MOD;

for(int i(l+1);i<=Hmin(l+k,r-2);++i)
if(co[l+1][i])
(f[l][r]+=f[i+1][r-1]+g[i+1][r-1])%=MOD;

for(int i(r-1);i>=Hmax(l+2,r-k);--i)
if(co[i][r-1])
(f[l][r]+=f[l+1][i-1]+g[l+1][i-1])%=MOD;

/*----G----*/

LL tmp(0);

for(int i(l+1);i<r-1;++i)
{
if(tmp<=i)
tmp=i+1;

while(tmp<r-1 and (s[tmp]=='?' or s[tmp]=='*'))
++tmp;

nex[i]=Hmin((LL)i+k+1,tmp);
}

tmp=0;

for(int i(l+2);i<=nex[l+1];++i)
(tmp+=f[i][r])%=MOD;

(g[l][r]+=((f[l][l+1]+g[l][l+1])%MOD*tmp))%=MOD;

for(int i(l+2);i<r-1;++i)
{
(tmp+=MOD-f[i][r])%=MOD;

for(int j(nex[i-1]+1);j<=nex[i];++j)
(tmp+=f[j][r])%=MOD;

(g[l][r]+=((f[l][i]+g[l][i])%MOD*tmp))%=MOD;
}
}
}

fw((f[n]+g[n]+MOD)%MOD,1);

Heriko Deltana;
}


# 「C」 Palindrome

How painful it is to test that there is no emptiness, and the violence points are gone

## 「C」 Brief description of ideas

In fact, because the palindrome string needs to be formed, when we perform the operation in step \ (I \), we can know that the number extracted by the operation \ (2n-i+1 \) should be the same as it.

Then, because the data can only be retrieved from two segments at a time, the original sequence is divided into two consecutive parts, so we consider using two deque to maintain the number taken out from the left end and the number taken out from the right end.

Then there are the following four cases (because the optimal scheme is required, it has been sorted in dictionary order):

• \If the beginning and end of (L \) are the same, then the \ (I \) operation is \ (L \), and the \ (2n-i+1 \) operation is \ (L. \)

• \If the header of (L \) is the same as that of \ (R \), then the operation of \ (I \) is \ (L \), and the operation of \ (2n-i+1 \) is \ (R. \)

• \If the tail of (R \) is the same as that of \ (L \), then the operation of \ (I \) is \ (R \), and the operation of \ (2n-i+1 \) is \ (L. \)

• \If the beginning and end of (R \) are the same, then the \ (I \) operation is \ (R \), and the \ (2n-i+1 \) operation is \ (R. \)

According to the optimal strategy, first run from the left end, and then run from the right end. If it cannot be formed twice, there is no solution.

## 「C」Code

CI MXX(1e6+4);

int n,m,a[MXX];

char ans[MXX];

deque<int> l,r;

I void Solve()
{
/*----Start At L----*/

l.clear();
r.clear();
l.push_back(a);
l.push_back(a);

for(int i(3);i<=m;++i)
if(l.front()!=l.back())
l.push_back(a[i]);
else
r.push_back(a[i]);

int flg(0),cnt(0);

while(cnt<n)
{
if(flg)
break;

flg=1;

if(l.size()>1 and l.front()==l.back())
{
flg=0;
ans[++cnt]='L',ans[m-cnt+1]='L';
l.pop_front();
l.pop_back();

continue;
}

if(l.size() and r.size() and l.front()==r.front())
{
flg=0;
ans[++cnt]='L',ans[m-cnt+1]='R';
l.pop_front();
r.pop_front();

continue;
}

if(l.size() and r.size() and l.back()==r.back())
{
flg=0;
ans[++cnt]='R',ans[m-cnt+1]='L';
l.pop_back();
r.pop_back();

continue;
}

if(r.size()>1 and r.front()==r.back())
{
flg=0;
ans[++cnt]='R',ans[m-cnt+1]='R';
r.pop_front();
r.pop_back();

continue;
}
}

if(!flg)
{
for(int i(1);i<=m;++i)
putchar(ans[i]);

puts("");

Heriko;
}

/*----Start At R----*/

l.clear();
r.clear();
r.push_front(a[m]);
r.push_front(a[m-1]);

for(int i(m-2);i;--i)
if(r.front()!=r.back())
r.push_front(a[i]);
else
l.push_front(a[i]);

l.push_back(r.front());
r.pop_front();

flg=cnt=0;

while(cnt<n)
{
if(flg)
{
puts("-1");

Heriko;
}

flg=1;

if(l.size()>1 and l.front()==l.back())
{
flg=0;
ans[++cnt]='L',ans[m-cnt+1]='L';
l.pop_front();
l.pop_back();

continue;
}

if(l.size() and r.size() and l.front()==r.front())
{
flg=0;
ans[++cnt]='L',ans[m-cnt+1]='R';
l.pop_front();
r.pop_front();

continue;
}

if(l.size() and r.size() and l.back()==r.back())
{
flg=0;
ans[++cnt]='R',ans[m-cnt+1]='L';
l.pop_back();
r.pop_back();

continue;
}

if(r.size()>1 and r.front()==r.back())
{
flg=0;
ans[++cnt]='R',ans[m-cnt+1]='R';
r.pop_front();
r.pop_back();

continue;
}
}

for(int i(1);i<=m;++i)
putchar(ans[i]);

puts("");
}

S main()
{
Files();

int T;fr(T);

while(T--)
{
fr(n);m=n*2;

for(int i(1);i<=m;++i)
fr(a[i]);

Solve();
}

Heriko Deltana;
}


# "Knot"

$NOIP2021 RP++.$