【2022 CCPC 桂林站】
蒟蒻侥幸铜(打铁原地退役算了
赛前看着参赛队伍大名单就感觉够呛,不少985/211等强校一队,rank+=n。实际战况确实如此,一边开题一边感慨这么多细节怎么这么多队直接冲过去了…换来的就是无尽的焦急……
A - Lily
赛时2分钟有人过A,签到题,急速跟题,6分钟1A拿下。
题意
‘L’ 的左右两侧不能有 ‘C’。
题解
所有两侧(包括自身)没有 ‘L’ 的字符替换为 ‘C’。
代码
#include<bits/stdc++.h>
#define ll long long
#define L(i,j,k) for(ll i=j;i<=k;++i)
#define R(i,j,k) for(ll i=j;i>=k;--i)
using namespace std;
const ll N=1e6+10;
ll n,m,k,p,t;
char s[N];
void solve(){
scanf("%lld",&n);
scanf("%s",s+1);
s[0]='.',s[n+1]='.';
L(i,1,n){
if(s[i-1]=='L'||s[i+1]=='L'||s[i]=='L');
else s[i]='C';
}
L(i,1,n)printf("%c",s[i]);printf("\n");
}
int main(){
ll cas=1;
while(cas--)solve();
}
M - Youth Finale
开完签到就在瞎晃,此时有队伍过了E,猜了个结论冲了一发成功WA掉,然后掉头开M。
题意
给定初始数组,有两种操作:1. 可以将最前面的元素移至最后;2. 将整个数组翻转。
给出冒泡排序的代码,要求每次操作后,输出当前数组进行冒泡排序的swap次数。
题解
可以发现冒泡排序的swap次数就是逆序对数量。
假设当前逆序对数量为 p p p,当前第一个元素为 a 1 a_1 a1,最后一个元素为 a n a_n an。
- 对于操作2,翻转整个数组,易得操作后的逆序对数 p ′ = n ( n − 1 ) 2 − p p'=\frac{n(n-1)}{2}-p p′=2n(n−1)−p。
- 对于操作1,如果当前操作2的数量为奇数,则等同于将最后一个元素移至最前面, p ′ = p − ( a 1 − 1 ) + ( n − a 1 ) p'=p-(a_1-1)+(n-a_1) p′=p−(a1−1)+(n−a1);如果当前操作2的数量为偶数,即将第一个元素移至最后面, p ′ = p − ( n − a n ) + ( a n − 1 ) p'=p-(n-a_n)+(a_n-1) p′=p−(n−an)+(an−1)。
代码
#include<bits/stdc++.h>
#define ll long long
#define L(i,j,k) for(ll i=j;i<=k;++i)
#define R(i,j,k) for(ll i=j;i>=k;--i)
using namespace std;
const ll N=1e6+10,inf=1e18;
ll dx[4]={
0,0,1,-1},dy[4]={
1,-1,0,0};
ll n,m,k,p,t,x,y,z;
ll ans;
ll a[N],tr[N];
char s[N];
deque<ll>sq;
void updata(ll i){
while(i<=n){
tr[i]++;
i+=i&-i;
}
}
ll qry(ll i){
ll res=0;
while(i>0){
res+=tr[i];
i-=i&-i;
}
return res;
}
void solve(){
scanf("%lld%lld",&n,&m);
k=0;
L(i,1,n){
scanf("%lld",&x);
k+=x-1-qry(x);
updata(x);
sq.push_back(x);
}
bool fg=0;
scanf("%s",s+1);
printf("%lld\n",k);
L(i,1,m){
if(s[i]=='S'){
if(!fg){
ll x=sq.front();sq.pop_front();
k-=x-1;k+=n-x;
sq.push_back(x);
}
else{
ll x=sq.back();sq