训练情况
赛后反思
组合数学还得加练,J题奇妙的乘法逆元预处理,开个unordered_map记忆化就过了?!,E题太头铁了,异或不算就直接交,F题又是急到没取模就直接交。
A题
字符串 Tomori
后面补上 Haruhikage
。
#include <bits/stdc++.h>
// #define int long long
#define endl '\n'
using namespace std;
void solve(){
string s; cin>>s;
cout<<s<<endl;
if(s == "Tomori") cout<<"Haruhikage"<<endl;
}
signed main(){
int T; cin>>T; while(T--)
solve();
return 0;
}
N题
找票数最多的人的名字
#include <bits/stdc++.h>
// #define int long long
#define endl '\n'
using namespace std;
string ans;
int now;
void solve(){
string s; cin>>s;
int x; cin>>x;
if(x > now){
now = x;
ans = s;
}
}
signed main(){
int T; cin>>T; while(T--)
solve();
cout<<ans<<endl;
return 0;
}
F题
由于这题保证字符串之间互不相同,所以它下面给的字符串并没有什么用,所以只需要 \(n\) 就可以计算答案,对于某一种缩写,对答案的贡献就是它的全排列,就是从 \(n\) 个字符串里面选 \(1,2,3,4,\cdots,n\) 的全排列,所以这题的答案是 \(A_n^1 + A_n^2 + A_n^3 \cdots A_n^n\)。
#include <bits/stdc++.h>
#define int long long
#define endl '\n'
using namespace std;
const int mod = 1e9 + 7;
void solve(){
int n; cin>>n;
int ans = 0;
int now = 1;
for(int i = n;i;i--){
now *= i;
now %= mod;
ans += now;
ans %= mod;
}
cout<<ans<<endl;
}
signed main(){
// int T; cin>>T; while(T--)
solve();
return 0;
}
I题
\(i\) 可以跳到 \(a_i\),对于两个不互通的环,我们需要交换两个环上的任意元素即可打通,所以最后需要交换的次数就是不同环的个数-1,所以我们直接并查集(DSU)维护,最后求有多少个不同的环,答案再减一。
#include <bits/stdc++.h>
// #define int long long
#define endl '\n'
using namespace std;
const int N = 1e5 + 3;
int fa[N];
int Find(int x){
if(fa[x] == x) return x;
return fa[x] = Find(fa[x]);
}
void Union(int x,int y){
x = Find(x); y = Find(y);
if(x == y) return;
fa[y] = x;
}
void solve(){
int n; cin>>n;
vector<int> a(n + 1);
for(int i = 1;i<=n;i++) fa[i] = i,cin>>a[i];
for(int i = 1;i<=n;i++){
Union(i,a[i]);
}
vector<bool> vis(n + 1);
int ans = 0;
for(int i = 1;i<=n;i++){
if(!vis[Find(i)]){
vis[Find(i)] = 1;
ans++;
}
}
cout<<ans-1<<endl;
}
signed main(){
int T; cin>>T; while(T--)
solve();
return 0;
}
E题
我们观察发现每一行每一列上的元素都互不相同才能让异或最小
#include <bits/stdc++.h>
// #define int long long
#define endl '\n'
using namespace std;
const int N = 507;
int n;
int a[N][N];
void solve(){
cin>>n;
for(int i = 0;i<n;i++){
for(int j = 0;j<n;j++){
a[i][j] = (i+j)%n;
}
}
int ans = 0;
for(int i = 0;i<n;i++) ans^=(i+1);
cout<<ans<<endl;
for(int i = 0;i<n;i++){
for(int j = 0;j<n;j++){
cout<<a[i][j]+1<<" ";
}
cout<<endl;
}
}
signed main(){
// int T; cin>>T; while(T--)
solve();
return 0;
}
J题
赢 \(n\) 次,输 \(n-1\) 次,输的位置可以在任意位置,有 \(C_{n+k-1}^k\) 种,由于是独立事件,概率就是每个事件概率的乘积,所以答案就是
\[\sum_{i=0}^{n-1}p^n \times (1-p)^i \times C_{n+k-1}^k \]#include <bits/stdc++.h>
#define int long long
#define endl '\n'
using namespace std;
const int mod = 1e9 + 7;
const int N = 2e5 + 3;
int jc[N];
inline int read(){
int s = 0; char c = getchar();
while(!isdigit(c)) c = getchar();
while(isdigit(c)){
s = (s << 1) + (s << 3) + (c ^ 48);
c = getchar();
}
return s;
}
void print(int x){
if(x > 9) print(x/10);
putchar(x%10+48);
}
int ksm(int a,int b){
int x = a;
int y = b;
int ans = 1;
while(y){
if(y&1){
ans *= x;
ans %= mod;
}
x*=x;
x%=mod;
y>>=1;
}
return ans;
}
unordered_map<int,int> pinv;
int inv(int x){
if(pinv[x]) return pinv[x];
return pinv[x] = ksm(x,mod-2);
}
void pre(){
jc[0] = 1;
for(int i = 1;i<=N-3;i++) jc[i] = jc[i-1]*i,jc[i] %= mod;
}
int C(int n,int m){
return (((jc[n]*inv(jc[n-m])) % mod)*inv(jc[m])) % mod;
}
void solve(){
int n,p,q; n = read(); p = read(); q = read();
int win = (p*inv(q)) % mod;
int lose = ((q-p)*inv(q)) % mod;
int powwin = ksm(win,n);
int powlose = 1;
int ans = 0;
for(int k = 0;k<=n-1;k++){
ans += (((powwin*powlose) % mod)*C(n+k-1,k)) % mod;
powlose *= lose; powlose%=mod;
ans %= mod;
}
print(ans); puts("");
}
signed main(){
pre();
int T; T = read(); while(T--)
solve();
return 0;
}
标签:return,int,long,2024,牛客,华为,solve,ans,define
From: https://www.cnblogs.com/longxingx/p/18580097