牛客小白月赛83

  • 总结&&吐槽:
    这场B wa了13发,笑死人了,真的会有这么菜的人么,读错题目了。下次读b这种题的时候要更加细心一点。

  • D.小天的子序列

    1. 题目大意:给定一个字符串全部由小写字母组成,然后又若干次查询,问有多少个以字符x开头以字符y结尾,并且长度为k。
    2. 思路分析:发现只要找到了x和y,那么只要长度大于等于k,那么就只要组合一下就能出答案。所以问题就回到了:怎么样去维护字符串?我们想要知道的东西无非就是两个,一是有多少个x开头y结尾的长度大于等于k的子串。然后思考一下就会发现可以去维护一个:以x字符开头,以y字符结尾,并且长度为len的子串有多少个。发现维护这个东西要O(n^2)的复杂度,由于给定字符串长度很小,所以直接维护就行。
    3. 注意事项:写模板的时候注意要开ll。。。
    4. 代码:
点击查看代码
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int mod = 998244353;
ll inv[501],fact[501];
ll res[26][26][501];
ll qpow(ll a,ll b) {
    ll res = 1;
    while(b) {
        if(b&1) res = res*a%mod;
        a = a*a%mod;
        b >>= 1;
    }
    return res;
}
ll C(int n,int m) {
    if(m > n) return 0;
    return (fact[n]*inv[m]%mod*inv[n - m]%mod);
}
void init() {
    inv[0] = 1,fact[0] = 1;
    for(int i = 1; i <= 500; i++) 
        fact[i] = fact[i - 1]*i%mod;
    inv[500] = qpow(fact[500],mod - 2);
    for(int i = 499; i >= 1; i--) 
        inv[i] = inv[i + 1]*(i + 1)%mod;
}
int main() {
    init();
    //cout << C(5,2) << "\n";
    int n;cin >> n;
    string s;cin >> s;
    s = " " + s;
    for(int i = 1; i <= n; i++) {
        for(int j = 1; j < i; j++) {
            res[s[j] - 'a'][s[i] - 'a'][i - j + 1]++;
        }
    }
    int q;
    cin >> q;
    while(q--) {
        char x,y;
        int len;
        cin >> x >> y;
        cin >> len;
        ll ans = 0;
        for(int i = len; i <= n; i++) {
            ans += (res[x - 'a'][y - 'a'][i]%mod*C(i - 2,len - 2))%mod;
        }
        cout << ans%mod << "\n";
    }
    return 0;
}
* E.小天的贪吃蛇
  1. 题目大意:给定两种贪吃蛇的运动轨迹,贪吃蛇在一个充满字符的举证中运动。然后给定若干查询,要回答贪吃蛇最多能吃掉多少字符。询问用3种,一种是修改,另外两种分别对应两种运动轨迹并且给定起点。每次输出最多能吃掉多少字符。
  2. 思路分析:因为轨迹是固定的,所以可以直接把二维平面变成一维的线段。然后用set记录每个字母出现的位置。其实求最多的并不是一个求最值问题,而是找到给定起点之后第一个不是该字符的其他字符。由于总共只有26个字母,所以二分一下就可以知道距离当前起点最近的字符是哪个,做差就可以。如果当前字符后面没有别的字符,那么代表当前点到最后点都是可以吃掉的。
  3. 代码:
点击查看代码
#include<bits/stdc++.h>                      
using namespace std;
const int N = 1e5 + 7;
typedef long long ll;
typedef pair<int,int> PII;
const int inf = 0x3f3f3f3f;
const int mod = 998244353;
int n,m;
vector<char> a[N];
int calcr(int x,int y) {
	int res = 0;
	if(x%2 == 0) res += (x - 1)*m + (m - y + 1);
	else res = (x - 1)*m + y;
	//cout << res << "\n";
	return res;
}
int calcc(int x,int y) {
	int res = 0;
	if(y&1) res += (y - 1)*n + x;
	else res += (y - 1)*n + (n - x + 1);
	return res;
}
void solve() {
	cin >> n >> m;
	for(int i = 1; i <= n; i++) {
		for(int j = 1; j <= m; j++) {
			char c;
			cin >> c;
			a[i].push_back(c);
		}
	}
	set<int> pos1[1000],pos2[1000];
	bool flag = 1;
	int cnt = 1;
	for(int i = 1; i <= n; i++) {
		if(!flag) {
			for(int j = m - 1; j >= 0; j--) {
				pos1[a[i][j] - 'a'].insert(cnt++);
			}
			flag = 1;
		} else {
			for(int j = 0; j < m; j++) {
				pos1[a[i][j] - 'a'].insert(cnt++);
			}
			flag = 0;
		}
	}
	flag = 1,cnt = 1;
	for(int j = 0; j < m; j++) {
		if(flag) {
			for(int i = 1; i <= n; i++) {
				pos2[a[i][j] - 'a'].insert(cnt++);
			}
			flag = 0;
		} else {
			for(int i = n; i >= 1; i--) {
				pos2[a[i][j] - 'a'].insert(cnt++);
			}
			flag = 1;
		}
	}
	/*for(int i = 0; i <= 25; i++) {
		if(!pos1[i].empty()) {
			cout << "i = " << i << "\n";
			for(auto j : pos1[i])
				cout << j << " ";
			cout << endl;
		}
	}*/
	int q;
	cin >> q;
	while(q--) {
		int op;
		cin >> op;
		if(op == 1) {
			int x,y;
			cin >> x >> y;
			char c;cin >> c;
			auto t1 = calcr(x,y),t2 = calcc(x,y);
			//cout << t1 << " " << t2 << "\n";
			char d = a[x][y - 1];
			pos1[d - 'a'].erase(t1),pos1[c - 'a'].insert(t1);
			pos2[d - 'a'].erase(t2),pos2[c - 'a'].insert(t2);
			a[x][y - 1] = c;
		} else if(op == 2) {
			int x,y;
			cin >> x >> y;
			char d = a[x][y - 1];
			int t1 = calcr(x,y);
			//cout << t1 << "\n";
			int minn = 1e8;
			for(int i = 0; i <= 25; i++) {
				if(i == (d - 'a')) continue;
				if(pos1[i].lower_bound(t1) != pos1[i].end()) {
					auto pos = *pos1[i].lower_bound(t1);
					minn = min(minn,pos);
				}
			}
			if(minn == 1e8) cout << n*m - t1 + 1 << "\n";
			else cout << minn - t1 << "\n";
		} else {
			int x,y;
			cin >> x >> y;
			char d = a[x][y - 1];
			int t1 = calcc(x,y);
			int minn = 1e8;
			for(int i = 0; i <= 25; i++) {
				if(i == (d - 'a')) continue;
				if(pos2[i].lower_bound(t1) != pos2[i].end()) {
					auto pos = *pos2[i].lower_bound(t1);
					minn = min(minn,pos);
				}
			}
			if(minn == 1e8) cout << n*m - t1 + 1 << "\n";
			else cout << minn - t1 << "\n";
		}
	}
}
 int main() {
	int t = 1;
	//cin >> t;
	while(t--) {
		solve();
	}
	return 0;
}

posted @ 2023-12-16 19:50  orzkeyhacker  阅读(26)  评论(0编辑  收藏  举报