燕山大学蓝桥杯校选新生组部分题解
情报传递
两个人碰到等于没碰到(灵魂互换),只需要统计两个方向能在规定之间内走完的人数即可。
#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 5;
int a[2][N];
int tail[2];
int main(){
int n, m, q;
scanf("%d%d%d", &n, &m, &q);
for(int i = 1; i <= m; ++i){
int x, t;
scanf("%d%d", &x, &t);
a[t][++tail[t]] = x;
}
int res = 0;
for(int i = 1; i <= tail[0]; ++i) if(a[0][i] <= q) ++res;
for(int i = 1; i <= tail[1]; ++i) if(n - a[1][i] <= q) ++res;
printf("%d\n", res);
return 0;
}
统计球迷
区间长度不变,所以我们开一个数组(桶),$f_i $ 表示支持 \(i\) 球队的人数。从右到左将新球迷的信息加入数组(桶),将走到区间外的球迷的信息从数组中删除来更新答案。如果一个数第一次在桶内出现,则球队的种数加1;同理,删除这个数后,这种球队的球迷数变为0,则球队种数减一。
有能力的同学可以学习一下莫队。
#include <bits/stdc++.h>
using namespace std;
#define rep(i, a, b) for(int i = a; i <= b; ++i)
#define per(i, a, b) for(int i = a; i >= b; --i)
const int N = 1e5 + 5;
int ask[N];
int ans[N], a[N], vis[N];
int n, m, L, q;
int main(){
scanf("%d%d%d%d", &n, &m, &L, &q);
rep(i, 1, m) scanf("%d", a + i);
rep(i, 1, q){
int x; scanf("%d", &x);
ask[i] = x;
}
int now = 0;
per(i, m, 1){
now += !vis[a[i]]++;
if(i + L <= m) now -= !--vis[a[i + L]];
ans[i] = now;
}
rep(i, 1, q) printf("%d\n", ans[ask[i]]);
return 0;
}
归
快速幂模版
#include <bits/stdc++.h>
using namespace std;
const int mod = 998244353;
int ksm(int a, int b){
int ans = 1;
while(b){
if(b & 1) ans = 1ll * ans * a % mod;
a = 1ll * a * a % mod;
b >>= 1;
}
return ans;
}
#define rep(i, a, b) for(int i = a; i <= b; ++i)
int main(){
int a,b;
cin>>a>>b;
cout<<ksm(a,b)<<endl;
return 0;
}