Dashboard - The 15th Chinese Northeast Collegiate Programming Contest - Codeforces
I
模拟
#include <bits/stdc++.h>
using i64 = long long;
using namespace std;
#define int long long
int mp[8] = {0, 7, 27, 41, 49, 63, 78, 108};
void solve()
{
int n; cin >> n;
vector<int>a(n + 1);
int s = 0;
for(int i = 1; i <= n; i ++)
{
cin >> a[i];
s += mp[a[i]];
}
if(s >= 120) s -= 50;
else if(s >= 89) s -= 30;
else if(s >= 69) s -= 15;
cout << s << '\n';
}
signed main()
{
std::ios::sync_with_stdio(false);
std::cin.tie(nullptr);
int t = 1; std::cin >> t;
while (t--)
{
solve();
}
}
E. Easy Math Problem
赛时太Push也不好,还是得好好看题目
样例即答案
#include <bits/stdc++.h>
#define rep(i, n) for (int i = 1; i <= (n); ++i)
#define int long long
using namespace std;
typedef long long ll;
const int N = 1e5 + 10;
void solve()
{
int x; cin >> x;
cout << 24 * x << " " << 4 << '\n';
cout << 2 * x << " " << 4 * x << " " << 6 * x << " " << 12 * x << '\n';
}
signed main()
{
ios::sync_with_stdio(0);
cin.tie(0); cout.tie(0);
int t = 1; cin >> t;
while(t --) solve();
}
M
看了好久没太懂题目意思,这是考的观察表格能力?。。。
①长度1、2特判
②韵母只有ang特判,其他的韵母能单独成字的都长度都小于3归为上一类(观察得到的。。。
③声母长度最多为2,剩下都为韵母
#include <bits/stdc++.h>
#define rep(i, n) for (int i = 1; i <= (n); ++i)
using namespace std;
typedef long long ll;
const int N = 1005;
map<string, string> mp =
{
{"q","q"}, {"iu","q"},{"w","w"}, {"ei","w"}, {"r","r"}, {"uan","r"},{"t","t"}, {"ue","t"},
{"y","y"}, {"un","y"},{"u","u"}, {"sh","u"}, {"i","i"}, {"ch","i"},{"o","o"}, {"uo","o"},
{"p","p"}, {"ie","p"},{"a","a"}, {"s","s"}, {"ong","s"}, {"iong","s"},{"d","d"}, {"ai","d"},
{"f","f"}, {"en","f"},{"g","g"}, {"eng","g"}, {"h","h"}, {"ang","h"},{"j","j"}, {"an","j"},
{"k","k"}, {"uai","k"},{"ing","k"}, {"l","l"}, {"uang","l"}, {"iang","l"},{"z","z"}, {"ou","z"},
{"x","x"}, {"ia","x"},{"ua","x"}, {"c","c"}, {"ao","c"}, {"v","v"},{"zh","v"}, {"ui","v"},
{"b","b"}, {"in","b"},{"n","n"}, {"iao","n"}, {"m","m"}, {"ian","m"}, {"e","e"}
};
signed main()
{
ios::sync_with_stdio(0);
// cin.tie(0); cout.tie(0);
string line;
while(getline(cin, line))
{
stringstream ss(line);
string s;
while(ss >> s)
{
if(s.size() == 2) cout << s << ' ';
else if(s.size() == 1) cout << s << s << ' ';
else
{
if(s.substr(0, 3) == "ang") cout << "a" << mp["ang"] << ' ';
else
{
if(mp.count(s.substr(0, 3)))
{
cout << mp[s.substr(0, 3)];
s = s.substr(3);
}
else if(mp.count(s.substr(0, 2)))
{
cout << mp[s.substr(0, 2)];
s = s.substr(2);
}
else if(mp.count(string(1, s[0])))
{
cout << mp[string(1, s[0])];
s = s.substr(1);
}
cout << mp[s] << ' ';
}
}
}
cout << '\n';
}
}
K
设伤害为 x ,小于 x 的边都是不存在的,大于等于的都是存在的。
先并查集+后缀和求剩m~1条边的联通情况
查询时二分找到该伤害能摧毁多少条边
#include <bits/stdc++.h>
#define rep(i, n) for (int i = 1; i <= (n); ++i)
//#define int long long
using namespace std;
typedef long long ll;
const int N = 1e5 + 10;
int p[N];
int find(int x)
{
if(x != p[x]) p[x] = find(p[x]);
return p[x];
}
void solve()
{
int n, m, Q; cin >> n >> m >> Q;
vector<ll>val(m + 1), cnt(n + 1);
for(int i = 1; i <= n; i ++) p[i] = i, cnt[i] = 1;
vector<pair<int, pair<int, int>>>a;
for(int i = 1; i <= m; i ++)
{
int x, y, k; cin >> x >> y >> k;
a.push_back(make_pair(k, make_pair(x, y)));
}
sort(a.begin(), a.end());
val[m] = 0;
for(int i = m - 1; i >= 0; i --)
{
int x = a[i].second.first, y = a[i].second.second;
x = find(x), y = find(y);
val[i] = val[i + 1];
if(x != y)
{
val[i] = val[i + 1] + (ll)cnt[x] * cnt[y];
cnt[x] += cnt[y], p[y] = x;
}
// cout << i << " " << val[i] << '\n';
}
while(Q --)
{
int x; cin >> x;
x = lower_bound(a.begin(), a.end(), make_pair(x, make_pair(0, 0))) - a.begin();
cout << val[x] << '\n';
}
}
signed main()
{
ios::sync_with_stdio(0);
cin.tie(0); cout.tie(0);
int t = 1; cin >> t;
while(t --) solve();
}
A
对于1~n的每个数i单独求贡献
放i选某行:n
选与i同行的元素:C(n * n, n * n - i) 从比i大的选
排该行的顺序:n!
排剩下的元素的顺序:(n * n - n)! 这一步不要漏了,放置完所有元素才算一种矩阵排法
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define int long long
const int mod = 998244353;
const int N = 3e7 + 10;
int fac[N], infac[N];
/*
7
1
2
3
4
5
1000
5000
*/
int qmi(int a, int b, int q)
{
a %= mod;
int res = 1ll;
while(b)
{
if(b & 1) res = (ll)res * a % mod;
a = (ll)a * a % mod;
b >>= 1ll;
}
return res % mod;
}
int A(int a, int b)
{
a = (a + mod) % mod, b = (b + mod) % mod;
if(a == 0 || b == 0) return 1;
int res = (ll)fac[a] * infac[a - b] % mod;
return res;
}
int C(int a, int b)
{
a = (a + mod) % mod, b = (b + mod) % mod;
if(a == 0 || b == 0) return 1;
int res = (ll)fac[a] * infac[b] % mod * infac[a - b] % mod;
return res;
}
void solve()
{
int n; cin >> n;
int ans = 0;
for(int i = 1; i <= n; i ++)
{
ans += n * fac[n * n - n] % mod * C(n * n - i, n - 1) % mod * fac[n];
ans %= mod;
}
cout << ans % mod << '\n';
}
signed main()
{
std::ios::sync_with_stdio(false);
std::cin.tie(nullptr);
fac[0] = 1;
for(int i = 1; i <= N; i ++)
{
fac[i] = (ll)fac[i - 1] * i % mod;
}
infac[N] = qmi(fac[N], mod - 2, mod);
for(int i = N - 1; i >= 0; i --)
{
infac[i] = (ll)infac[i + 1] * (i + 1) % mod;
}
int t = 1; std::cin >> t;
while (t --)
{
solve();
}
}
C
属于有点难想状态设计,但是看题解一眼懂类型
贴个大佬代码【解题报告】2021CCPC东北四省赛_2021东北四省赛-CSDN博客
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+10,mod=998244353;
typedef long long LL;
int n;
vector<int>v[N];
LL f[N][3];
void dfs(int u,int fa){
f[u][0]=f[u][1]=f[u][2]=1;
for(int j:v[u]){
if(j==fa)continue;
dfs(j,u);
//递归完后开始更新子树,然后一层层向上更新
f[u][0]=f[u][0]*(f[j][0]+f[j][1])%mod;
f[u][1]=f[u][1]*(f[j][0]+f[j][1]+f[j][2])%mod;
f[u][2]=f[u][2]*f[j][0]%mod;
}
f[u][1]-=f[u][2];
if(f[u][1]<0)f[u][1]+=mod;
}
int main(){
int T;
while(~scanf("%d",&T)){
while(T--){
scanf("%d",&n);
for(int i=1;i<=n;i++)v[i].clear();
for(int i=0,a,b;i<n-1;i++){
scanf("%d%d",&a,&b);
v[a].push_back(b);
v[b].push_back(a);
}
dfs(1,-1);
printf("%lld\n",(f[1][0]+f[1][1])%mod);
}
}
return 0;
}
后面的题随缘补