燕山大学蓝桥杯校选新生组部分题解

情报传递

两个人碰到等于没碰到(灵魂互换),只需要统计两个方向能在规定之间内走完的人数即可。

#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;
}

posted @ 2021-12-12 08:21  __int256  阅读(184)  评论(0编辑  收藏  举报