A
#include <bits/stdc++.h>
#define x first
#define y second
#define int long long
using namespace std;
typedef unsigned long long ULL ;
typedef pair<int,int> PII ;
typedef pair<long double,long double> PDD ;
const int N = 100010 , M = 6000000 , mod = 998244353 ;
int n ;
int a[N] ;
void solve()
{
cin >> n ;
cout << n * 2 << "\n" ;
}
signed main()
{
std::ios::sync_with_stdio(false) , cin.tie(0) , cout.tie(0) ;
int t = 1 ;
cin >> t ;
while (t --) solve() ;
return 0;
}
B
#include <bits/stdc++.h>
#define x first
#define y second
#define int long long
using namespace std;
typedef unsigned long long ULL ;
typedef pair<int,int> PII ;
typedef pair<long double,long double> PDD ;
const int N = 100010 , M = 6000000 , mod = 998244353 ;
int n , k , x ;
int a[N] ;
void solve()
{
cin >> n >> k >> x ;
int sum = 0 , res = 0 ;
for(int i = 1 ; i <= n ; i ++) cin >> a[i] , sum += a[i] ;
if(sum >= x) {
res = n * (k - 1) ;
int u = 0 ;
for(int i = n ; i >= 1 ; i --) {
u += a[i] ;
if(u >= x) res ++ ;
}
}
else {
int u = x / sum , y = x % sum ;
if(k > u) {
res = n * (k - (u + 1)) ;
int p = 0 ;
if(y == 0) res ++ ;
for(int i = n ; i >= 1 ; i --) {
p += a[i] ;
if(p >= y) res ++ ;
}
}
else if(k == u && y == 0) res ++ ;
}
cout << res << "\n" ;
}
signed main()
{
std::ios::sync_with_stdio(false) , cin.tie(0) , cout.tie(0) ;
int t = 1 ;
cin >> t ;
while (t --) solve() ;
return 0;
}
C
并查集。每次将一个数置为0,需要修改所有与之相关的位置(如4,2,3,1,将第一个位置置为0,则需要修改1和4位置),所以可以用并查集维护是否在一个集合和集合中个数的数量。
#include <bits/stdc++.h>
#define x first
#define y second
#define int long long
using namespace std;
typedef unsigned long long ULL ;
typedef pair<int,int> PII ;
typedef pair<long double,long double> PDD ;
const int N = 100010 , M = 6000000 , mod = 998244353 ;
int n ;
int a[N] , p[N] , s[N] ;
int find(int x) {
if(p[x] != x) p[x] = find(p[x]) ;
return p[x] ;
}
void solve()
{
cin >> n ;
for(int i = 1 ; i <= n ; i ++) cin >> a[i] ;
for(int i = 1 ; i <= n ; i ++) p[i] = i , s[i] = 1 ;
for(int i = 1 ; i <= n ; i ++) {
int x = find(i) , y = find(a[i]) ;
if(x != y) {
p[x] = y ;
s[y] += s[x] ;
}
}
set<int> st ;
int res = 0 ;
for(int i = 1 ; i <= n ; i ++) {
int x ;
cin >> x ;
int fx = find(x) ;
if(!st.count(fx)) {
res += s[fx] ;
st.insert(fx) ;
}
cout << res << " " ;
}
cout << "\n" ;
}
signed main()
{
std::ios::sync_with_stdio(false) , cin.tie(0) , cout.tie(0) ;
int t = 1 ;
cin >> t ;
while (t --) solve() ;
return 0;
}
D
排列组合题,考察逆元和DP,预处理出fac和infac数组。在遍历每个字母数量时,采用01背包的思想。
#include <bits/stdc++.h>
#define x first
#define y second
#define int long long
using namespace std;
typedef unsigned long long ULL ;
typedef pair<int,int> PII ;
typedef pair<long double,long double> PDD ;
const int N = 500010 , M = 6000000 , mod = 998244353 ;
int n ;
int a[30] , fa[N] , f[N] , infa[N] ;
int qmi(int a , int k) {
int res = 1 ;
while (k) {
if(k & 1) res = res * a % mod ;
a = a * a % mod ;
k >>= 1 ;
}
return res ;
}
void init() {
fa[0] = 1 , infa[0] = 1 ;
for(int i = 1 ; i <= 500000 ; i ++){
fa[i] = fa[i - 1] * i % mod ;
infa[i] = infa[i - 1] * qmi(i , mod - 2) % mod ;
}
}
void solve()
{
int sum = 0 ;
for(int i = 0 ; i <= 25 ; i ++) cin >> a[i] , sum += a[i] ;
int x = (sum + 1) / 2 , y = sum / 2 ;
for(int i = 0 ; i <= 25 ; i ++)
if(a[i] > x) {
cout << "0" << "\n" ;
return;
}
f[0] = 1 ;
for(int i = 1 ; i <= x ; i ++) f[i] = 0 ;
int res = fa[x] * fa[y] % mod ;
for(int i = 0 ; i <= 25 ; i ++) {
if(a[i]) {
res = res * infa[a[i]] % mod ;
for(int j = x ; j >= a[i] ; j --)
f[j] = f[j] + f[j - a[i]] ;
}
}
res = res * f[x] % mod ;
cout << res << "\n" ;
}
signed main()
{
std::ios::sync_with_stdio(false) , cin.tie(0) , cout.tie(0) ;
int t = 1 ;
cin >> t ;
init() ;
while (t --) solve() ;
return 0;
}