「CSP-S 2021」
A. 廊桥分配
签到题,注意数据范围贪心即可.
A_code
#include <bits/stdc++.h>
using namespace std;
namespace BSS
{
#define ll long long
#define lf double
#define ull unsigned ll
#define mp make_pair
#define lb lower_bound
#define ub upper_bound
#define lbt(x) ((x) & (-(x)))
#define Fill(x, y) memset(x, y, sizeof(x))
#define Copy(x, y) memcpy(x, y, sizeof(x))
#define File(x) freopen(#x ".in", "r", stdin), freopen(#x ".out", "w", stdout)
auto read = []() -> ll
{
ll w = 0;
char ch;
bool cit = 1;
while (!isdigit(ch = getchar()))
if (ch == '-')
cit = 0;
while (isdigit(ch))
w = (w << 3) + (w << 1) + (ch ^ 48), ch = getchar();
return cit ? w : (-w);
};
}
using namespace BSS;
const ll N = 2e5 + 21;
ll n, alls;
ll m[3], sum[3];
ll ans[3][N], pre[3][N];
set<pair<ll, ll>> s;
auto Work = [](ll op) -> void
{
ll a, b, cnt = 0;
for (ll i = 1; i <= m[op]; i++)
{
a = read(), b = read();
s.insert(mp(a, b));
}
while (s.size())
{
auto it = s.begin();
s.erase(it);
auto it2 = s.lb(mp(it->second, 0));
ans[op][++cnt] = 1;
while (it2 != s.end())
{
b = it2->second, s.erase(it2);
it2 = s.lb(mp(b, 0));
ans[op][cnt]++;
}
}
sum[op] = cnt;
};
signed main()
{
n = read(), m[0] = read(), m[1] = read();
Work(0), Work(1);
for (ll i = 1; i <= n; i++)
pre[0][i] = pre[0][i - 1] + ans[0][i];
for (ll i = 1; i <= n; i++)
pre[1][i] = pre[1][i - 1] + ans[1][i];
for (ll i = 0; i <= n; i++)
alls = max(alls, pre[0][i] + pre[1][n - i]);
printf("%lld\n", alls), exit(0);
}
B. 括号序列
看错题,基本没怎么向正确的方向思考.
B_code
#include<bits/stdc++.h>
using namespace std;
namespace BSS{
#define ll long long
#define lf double
#define ull unsigned ll
#define mp make_pair
#define lb lower_bound
#define ub upper_bound
#define lbt(x) ((x)&(-(x)))
#define Fill(x,y) memset(x,y,sizeof(x))
#define Copy(x,y) memcpy(x,y,sizeof(x))
#define File(x) freopen(#x".in","r",stdin),freopen(#x".out","w",stdout)
auto read=[]()->ll{
ll w=0; char ch; bool cit=1;
while(!isdigit(ch=getchar())) if(ch=='-') cit=0;
while(isdigit(ch)) w=(w<<3)+(w<<1)+(ch^48),ch=getchar();
return cit?w:(-w);
};
}using namespace BSS;
const ll N=1005,mod=1e9+7;
char ch[N];
ll m,n;
ll c[N];
ll f[N][N],g[N][N],s[N][N];
inline void inc(ll &x,ll y){ x=(x+y)%mod; }
signed main(){
n=read(),m=read(); scanf("%s",ch+1); ll lst;
for(ll i=1;i<=n;i++){
if(ch[i]=='(') c[i]=1;
if(ch[i]=='*') c[i]=2;
if(ch[i]==')') c[i]=4;
if(ch[i]=='?') c[i]=7;
s[i][i]=((c[i]&2)>0),s[i][i-1]=1;
for(ll j=i-1;j>=1;j--)
if(!(s[j][i]=(s[j+1][i]&((c[j]&2)>0)))) break;
}
for(ll i=1,j=2;j<=n;i++,j++){
if((c[i]&1) and (c[j]&4)) f[i][j]=1;
}
for(ll k=3;k<=n;k++){
for(ll l=1,r=l+k-1;r<=n;l++,r++){
if((!(c[l]&1)) or (!(c[r]&4))) continue;
if(r-l-1<=m) inc(f[l][r],s[l+1][r-1]);
inc(f[l][r],f[l+1][r-1]+g[l+1][r-1]);
for(ll i=1;i<=min(m,k);i++){
if(s[l+1][l+i]) inc(f[l][r],f[l+i+1][r-1]+g[l+i+1][r-1]);
if(s[r-i][r-1]) inc(f[l][r],f[l+1][r-i-1]+g[l+1][r-i-1]);
}
lst=0;
for(ll i=l+1,j=i+1;i<r;i++,j=max(i+1,j)){
while(j<r and j-i-1<=m and s[i+1][j-1]) inc(lst,f[j][r]),j++;
inc(g[l][r],(f[l][i]+g[l][i])*lst%mod),lst=(lst-f[i+1][r]+mod)%mod;
}
}
}
printf("%lld\n",(f[1][n]+g[1][n])%mod);
exit(0);
}
C. 回文
不是很难,像个模拟.
C_code
#include<bits/stdc++.h>
using namespace std;
namespace BSS{
#define ll int
#define lf double
#define ull unsigned ll
#define mp make_pair
#define lb lower_bound
#define ub upper_bound
#define lbt(x) ((x)&(-(x)))
#define Fill(x,y) memset(x,y,sizeof(x))
#define Copy(x,y) memcpy(x,y,sizeof(x))
#define File(x) freopen(#x".in","r",stdin),freopen(#x".out","w",stdout)
auto read=[]()->ll{
ll w=0; bool cit=1; char ch;
while(!isdigit(ch=getchar())) if(ch=='-') cit=0;
while(isdigit(ch)) w=(w<<3)+(w<<1)+(ch^48),ch=getchar();
return cit?w:(-w);
};
} using namespace BSS;
const ll N=1e6+21;
char ans[N];
ll m,n,cnt,head,tail;
ll c[N],o[N],val[N],vis[N];
ll pos[2][N];
auto Work=[]()->void{
n=read(),m=n<<1,cnt=0,c[m+1]=0; ll x,y,flag=1;
for(ll i=0;i<=n;i++) vis[i]=0;
for(ll i=1;i<=m;i++) c[i]=read(),pos[vis[c[i]]][c[i]]=i,vis[c[i]]=1,o[i]=c[i];
val[1]=1,c[1]=0,val[m]=1; head=1,tail=m;
for(ll i=2,l=pos[1][o[1]],r=l;i<=n;i++){
while(!c[head]) head++; while(!c[tail]) tail--;
x=c[l-1],y=c[r+1];
// cout<<l<<' '<<r<<' '<<x<<' '<<y<<endl;
if(x!=c[head] and y!=c[head] and x!=c[tail] and y!=c[tail]){ flag=0; break ; }
if(x==c[head] and l-1>head) { c[head]=0,l--,val[i]=1,val[m-i+1]=1; continue; }
if(y==c[head] and r+1>head) { c[head]=0,r++,val[i]=1,val[m-i+1]=2; continue; }
if(x==c[tail] and l-1<tail) { c[tail]=0,l--,val[i]=2,val[m-i+1]=1; continue; }
if(y==c[tail] and r+1<tail) { c[tail]=0,r++,val[i]=2,val[m-i+1]=2; continue; }
flag=0; break;
}
if(flag){
for(ll i=1;i<=m;i++)
putchar( (val[i]&1) ? 'L' : 'R' );
puts(""); return ;
}
reverse(o+1,o+1+m); flag=1;
for(ll i=0;i<=n;i++) vis[i]=0;
for(ll i=1;i<=m;i++) c[i]=o[i],pos[vis[c[i]]][c[i]]=i,vis[c[i]]=1,val[i]=0;
val[1]=1,c[1]=0,val[m]=2; head=1,tail=m;
for(ll i=2,l=pos[1][o[1]],r=l;i<=n;i++){
while(!c[head]) head++; while(!c[tail]) tail--;
x=c[l-1],y=c[r+1];
// cout<<l<<' '<<r<<' '<<x<<' '<<y<<endl;
if(x!=c[head] and y!=c[head] and x!=c[tail] and y!=c[tail]){ flag=0; break ; }
if(y==c[tail] and r+1<tail) { c[tail]=0,r++,val[i]=2,val[m-i+1]=2; continue; }
if(x==c[tail] and l-1<tail) { c[tail]=0,l--,val[i]=2,val[m-i+1]=1; continue; }
if(y==c[head] and r+1>head) { c[head]=0,r++,val[i]=1,val[m-i+1]=2; continue; }
if(x==c[head] and l-1>head) { c[head]=0,l--,val[i]=1,val[m-i+1]=1; continue; }
flag=0; break;
}
if(flag){
for(ll i=1;i<=m;i++)
putchar( (val[i]&1) ? 'R' : 'L' );
puts(""); return ;
}
puts("-1");
};
signed main(){
for(int Ts=read();Ts;Ts--) Work();
exit(0);
}
D. 交通规划
不会,先鸽.