比赛传送门

目录

A R 通过

思路:可以发现,第一个R前面的贡献乘上第三个R后面的贡献即为答案 具体看代码

#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N = 2e5 + 7;
vector<int>v;
int n,k,cnt,pos1,pos2,snt,ans,t;
int p[N],q[N];//p[i] 存前方最近的边界,q[i]存后方最近的边界
string s;
signed main(){
    scanf(" %lld%lld",&n,&k);
    cin>>s;
    s = '0' + s;
    for (int i=1;i<=n;i++){
        if(s[i]=='P') snt = i;
        p[i] = snt;
    }
    snt = n + 1;
    for (int i=n;i>=1;i--){
         if(s[i]=='P') snt = i;
        q[i] = snt;
    }
    for (int i=1;i<=n;i++){
        if (s[i]=='P') cnt = 0,v.clear(),t=0;
        if (s[i]=='R'){
            v.push_back(i);
            cnt++;
            if (cnt==1){
                pos1 = v[t];//pos1标记第一个R的位置
            }
            if (cnt==k){
                pos2 = i;//pos2标记第k个R的位置
                ans += (pos1 - p[i]) * (q[i] - pos2);
            }
            else if (cnt>k){
                t++;pos1 = v[t];
                pos2 = i;//pos2标记第k个R的位置
                ans += (pos1 - v[t-1]) * (q[i] - pos2);
            }
        }
    }
    printf("%lld",ans);
}

B 进制 未通过

待补

C 蓝彗星 通过

注意到数据范围最大为2e5,故枚举坐标点,用两个差分数组模拟每个点的状态

#include <bits/stdc++.h>
using namespace std;
const int N = 2e5 + 7;
int n,t,cnt,snt,ans;
int b[N],r[N];
string s;
signed main(){
    scanf(" %d%d",&n,&t);
    cin>>s;
    s = '0' + s;
    for (int i=1;i<=n;i++){
        int x;scanf(" %d",&x);
        if (s[i]=='B'){
            b[x]++,b[x+t]--;
        }
        else {
            r[x]--,r[x+t]++;
        }
    }
    for (int i=0;i<=2e5;i++){
        cnt += b[i];
        snt += r[i];
        if (cnt>0&&snt==0) ans++;
    }
    cout<<ans;
}

D 雪色光晕 未通过

待补

E 真假签到题 通过

签到,输出x即可,注意要开long long

#include <bits/stdc++.h>
using namespace std;
signed main(){
	long long x;scanf("%lld",&x);
    printf("%lld",x);
}

F 小红的记谱法 通过

简单模拟,cnt记录个数

#include <bits/stdc++.h>
using namespace std;
string s,s1;
int cnt;
map<char,int>mp;
signed main(){
    mp['C'] = 1;mp['D'] = 2;mp['E'] = 3;mp['F'] = 4;
    mp['G'] = 5;mp['A'] = 6;mp['B'] = 7;
    cin>>s;
    for (int i=0;i<s.size();i++){
        if (s[i]=='<') cnt--;
        else if (s[i]=='>') cnt++;
        else {
            printf("%d",mp[s[i]]);
            int x = abs(cnt);
            if (cnt<0){
                for (int i=1;i<=x;i++){
                    printf(".");
                }
            }
            else if (cnt>0){
                 for (int i=1;i<=x;i++){
                    printf("*");
                }
            }
        }
    }
}

G 子序列权值乘积 未通过

H 真真真真真签到题 通过

简单几何数学

#include <bits/stdc++.h>
using namespace std;
signed main(){
    double x;scanf("%lf",&x);
    double y = 8.0 * x * x * x / 3.0 / sqrt(3.0);
    printf("%.8lf",y);
}

I 爆炸的符卡洋洋洒洒 通过

01背包,注意到求k的倍数,故对花费量取模k,注意边界要置负数而不能默认为0

#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N = 1e3 + 7;
const int INF = -1e18;
int n,k;
int a[N],b[N];
int dp[N][N];
signed main(){
    scanf(" %lld%lld",&n,&k);
    for (int i=0;i<=n;i++){
        for (int j=0;j<=k;j++){
            dp[i][j] = INF;
        }
    }
    for (int i=1;i<=n;i++) scanf(" %lld%lld",a+i,b+i),dp[i][a[i]%k] = b[i];
    for (int i=1;i<=n;i++){
        for (int j=0;j<k;j++){
            if (dp[i][j]==INF) dp[i][j] = dp[i-1][j];
            if (dp[i][j]!=INF||dp[i-1][(j-a[i]%k+k)%k]!=INF) dp[i][j] = max(dp[i-1][(j-a[i]%k+k)%k]+b[i],dp[i][j]);
            //printf("dp[%lld][%lld] = %lld\n",i,j,dp[i][j]);
        }
    }
    if (dp[n][0]!=INF) cout<<dp[n][0];
    else cout<<-1;
}

J 区间合数的最小公倍数 通过

将区间内所有合数分解质因数,记录每个质因子出现的最大个数,再将其相乘即为答案

#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N = 3e4 + 7;
const int mod = 1000000007;
int cnt,prime[N];
bool vis[N];
int mp[N],l,r;
bool flag;
int qmi(int a,int b){
    int ans = 1,base = a;
    while (b){
        if (b&1) ans = (ans * base) % mod;
        base = (base * base) % mod;
        b >>= 1;
    }
    return ans;
}
void get_prime(){
    for (int i=2;i<=3e4;i++){
        if (!vis[i]) prime[cnt++] = i;
        for (int j=0;j<cnt&&i*prime[j]<=3e4;j++){
            vis[prime[j]*i] = 1;
            if (i%prime[j]==0) break;
        }
    }
}
signed main(){
    get_prime();
    scanf(" %lld%lld",&l,&r);
    for (int i=l;i<=r;i++){
        if (!vis[i]) continue;
        for (int j=0;j<cnt&&prime[j]<i;j++){
            int x = i;
            if (x%prime[j]==0) {
                int snt = 0;
                while (x%prime[j]==0&&x>0) snt++,x /= prime[j];
                mp[prime[j]] = max(mp[prime[j]],snt);
            }
        }
    }
    int ans = 1;
    for (int j=0;j<cnt;j++){
        if (!mp[prime[j]]) continue;
        flag = 1;
        //cout<<mp[prime[j]]<<endl;
        ans = ((qmi(prime[j],mp[prime[j]])%mod)*ans) % mod;
    }
    if (flag) printf("%lld",ans);
    else printf("-1");
}

K 小红的真真假假签到题题 通过

简单构造

#include <bits/stdc++.h>
#define int long long
using namespace std;
int dig(int x){
    int cnt = 0ll;
    while (x){
        cnt++;
        x >>= 1ll;
    }
    return cnt;
}
signed main(){
    int x;scanf("%lld",&x);
    int y = (x<<dig(x)) + x;
    printf("%lld",y);
}

L 在这冷漠的世界里光光哭哭 未通过

待补