B Base Conversion Master
题目大意
有一个初始
思路
我们很容易发现如果
对于出现长度为
代码
#include<bits/stdc++.h>
#define IOS ios::sync_with_stdio(0);cin.tie(0);cout.tie(0)
#define endl '\n'
#define PII pair<int,int>
#define F first
#define S second
#define int long long
#define i128 __int128_t
#define all(vec) vec.begin(),vec.end()
#define vi vector<int>
#define vii vector<vector<int>>
using namespace std;
const int N = 5e5+10 ;
const int M = 1e3+10 ;
const int INF = 0x3f3f3f3f3f3f3f3f;
const int MOD1 = 1e9 + 7 ;
const int MOD2 = 998244353 ;
const double eps = 1e-9 ;
int gcd(int a, int b){ return b == 0 ? a : gcd(b, a%b); }
int lcm(int a, int b){ return a * b / gcd(a,b); }
int _ = 1 ;
int ans = 0 ;
int n , m, k, q, y ;
int qmi(int a, int b){
int res = 1 ;
while(b){
if(b&1){
if( a > 1e9 || res * a > 1e9) return 1e9 + 10 ;
res = res * a ;
}
b >>= 1 ;
a = a * a ;
}
return res ;
}
void solve(){
cin >> n >> y >> m ;
vii a(n) ;
int len, x ;
int me = -1 ;
for(int i = 0 ; i < n ; ++ i){
cin >> len ;
if(len == 1){
me = i ;
}
for(int j = 0 ; j < len ; ++ j){
cin >> x ;
a[i].push_back(x) ;
}
}
if(me != -1){// 说明无论初始如何选一定会从 me 的 值开始
int s = a[me][0] ;
int la = 0 ;
for(int i = me + 1 ; i < n ; ++ i){
la = s ;
s = 0 ;
for(int j = 0 ; j < a[i].size() ; ++ j){
if(a[i][j] >= la){
cout << -1 << " " << -1 << endl ;
return ;
}
s = min(s * la + a[i][j],1000000010LL);
}
}
if(s == y){//但是要保证之前的位置都是合法的
int l = 2 , r = m ;
int l1 = m + 1 ;
auto check3 = [&](int x) -> bool {// s 越大月能满足
int s = 0 ;
int la = x ;
for(int i = 0 ; i <= me ; ++ i){
for(int j = 0 ; j < a[i].size() ; ++ j ){
if(a[i][j] >= la ) return false ;
s = min(s * la + a[i][j],1000000010LL);
}
la = s ;
s = 0 ;
}
return true ;
};
while(l <= r){
int mid = l + r >> 1 ;
if(check3(mid)){
l1 = mid ;
r = mid -1 ;
}else{
l = mid + 1 ;
}
}
if(l1<=m){
cout << l1 << " " << m << endl ;
}else{
cout << -1 << " " << -1 << endl ;
}
}else{
cout << -1 << " " << -1 << endl ;
}
return ;
}
auto check1 = [&](int x) -> bool {// s 越大月能满足
int s = 0 ;
int la = x ;
for(int i = 0 ; i < n ; ++ i){
for(int j = 0 ; j < a[i].size() ; ++ j ){
if(a[i][j] >= la ) return false ;
s = min(s * la + a[i][j],1000000010LL);
if(s > y){
return true;
}
}
la = s ;
s = 0 ;
}
return la >= y ;
};
auto check2 = [&](int x) -> bool {
int s = 0 ;
int la = x ;
for(int i = 0 ; i < n ; ++ i){
for(int j = 0 ; j < a[i].size() ; ++ j ){
if(a[i][j] >= la ) return true ;
s = min(s * la + a[i][j],1000000010LL);
if(s > y){
return false;
}
}
la = s ;
s = 0 ;
}
return la <= y ;
};
int l1 = m + 1 ;
int l = 2, r = m ;
while(l <= r){
int mid = l + r >> 1 ;
if(check1(mid)){
l1 =mid ;
r = mid - 1 ;
}else{
l = mid + 1 ;
}
}
int r1 = 1 ;
l = 2, r = m ;
while(l <= r){
int mid = l + r >> 1 ;
if(check2(mid)){
r1 = mid ;
l = mid + 1 ;
}else{
r = mid - 1 ;
}
}
auto check4 = [&](int x) -> bool {
int s = 0 ;
int la = x ;
for(int i = 0 ; i < n ; ++ i){
for(int j = 0 ; j < a[i].size() ; ++ j ){
if(a[i][j] >= la ) return false ;
s = min(s * la + a[i][j],1000000010LL);
if(s > y){
return false;
}
}
la = s ;
s = 0 ;
}
return la == y ;
};
if(l1 > r1 || l1 > m || r1 < 2 || !check4(l1) || !check4(r1)){
cout << -1 << " " << -1 << endl ;
return ;
}
cout << l1 << " " << r1 << endl ;
}
signed main(){
IOS ;
cin >> _ ;
while(_ --){
solve() ;
}
return 0;
}
C Stack
题目大意
思路
我们设
第一项表示放在最后一个位置,第二项表示放在除最后一个位置的其
那么
设
设
设
综上
以此直接递推即可
代码
#include<bits/stdc++.h>
#define IOS ios::sync_with_stdio(0);cin.tie(0);cout.tie(0)
#define endl '\n'
#define double long double
#define PII pair<int,int>
#define F first
#define S second
#define int long long
#define i128 __int128_t
#define all(vec) vec.begin(),vec.end()
#define vi vector<int>
#define vii vector<vector<int>>
using namespace std;
const int N = 5e5+10 ;
const int M = 1e3+10 ;
const int INF = 0x3f3f3f3f3f3f3f3f;
const int MOD1 = 1e9 + 7 ;
const int MOD2 = 998244353 ;
const double eps = 1e-9 ;
int gcd(int a, int b){ return b == 0 ? a : gcd(b, a%b); }
int lcm(int a, int b){ return a * b / gcd(a,b); }
int _ = 1 ;
int ans = 0 ;
int n , m, k, q ;
int qmi(int a, int b){
int res = 1 ;
while(b){
if(b & 1) res = res * a % MOD2 ;
b >>= 1 ;
a = a * a % MOD2 ;
}
return res ;
}
int f[N], g[N], h[N] ;
int fac[N] ;
void init(){
fac[1] = 1;
for(int i = 2 ; i< N ; ++ i){
fac[i] = fac[i-1] * i % MOD2 ;
}
f[1] = 1 ;
g[1] = 1 ;
h[1] = 1 ;
for(int i = 2; i < N ; ++ i){
f[i] = (i * f[i-1] % MOD2 + fac[i-1]) % MOD2 ;
g[i] = (i * g[i-1] % MOD2 + 2 * f[i-1] + fac[i-1]) % MOD2 ;
h[i] = (((i * h[i-1] % MOD2 + 3 * g[i-1] % MOD2) % MOD2 + 3 * f[i-1] % MOD2) % MOD2 + fac[i-1]) % MOD2 ;
}
}
void solve(){
cin >> n ;
cout << h[n] << endl ;
}
signed main(){
IOS ;
init() ;
cin >> _ ;
while(_ --){
solve() ;
}
return 0;
}
D Beautiful Matrix
思路
因为
所以
我们设
我们假设
答案就是
由广义牛顿二项式定理得
所以说
所以答案就是
#include<bits/stdc++.h>
#define IOS ios::sync_with_stdio(0);cin.tie(0);cout.tie(0)
#define endl '\n'
#define PII pair<int,int>
#define F first
#define S second
#define int long long
#define i128 __int128_t
#define all(vec) vec.begin(),vec.end()
#define vi vector<int>
#define vii vector<vector<int>>
using namespace std;
const int N = 5e5+10 ;
const int M = 1e3+10 ;
const int INF = 0x3f3f3f3f3f3f3f3f;
const int MOD1 = 1e9 + 7 ;
const int MOD2 = 998244353 ;
const double eps = 1e-9 ;
int gcd(int a, int b){ return b == 0 ? a : gcd(b, a%b); }
int lcm(int a, int b){ return a * b / gcd(a,b); }
int _ = 1 ;
int ans = 0 ;
int n , m, k, q, y ;
int qmi(int a, int b){
int res = 1 ;
while(b){
if(b&1) res = res * a % MOD2 ;
b >>= 1 ;
a = a * a % MOD2;
}
return res ;
}
void solve(){
ans = 0 ;
cin >> n >> m ;
int a1 = 1 , a2 = 1 ;
for(int i = 1 ; i <= m ; ++ i){
a1 = a1 * ((n * (n-1) + m - i + 1) % MOD2) % MOD2 ;
a2 = a2 * i % MOD2 ;
}
ans = a1 * qmi(a2,MOD2 - 2) % MOD2 ;
cout << ans << endl ;
}
signed main(){
IOS ;
while(_ --){
solve() ;
}
return 0;
}
D Maximum GCD
题目大意
给定一个长度为
思路
当区间选择就是整个数组时,根据上式吗实质上就是
当选择的区间不包含第一个数
如果数量只有零个,呢么就不用选择区间
如果数量只有一个,那么就是在这个位置到最后的位置的区间都加 x,
如果数量只有两个,还需要判断这两个数是不是关于 当前枚举
如果数量大于两个,呢么一定没有合法答案。
因为我们枚举的的答案中也包含了最大答案的
当选择的区间不包含最后数
代码
#include<bits/stdc++.h>
#define IOS ios::sync_with_stdio(0);cin.tie(0);cout.tie(0)
#define endl '\n'
#define double long double
#define PII pair<int,int>
#define F first
#define S second
#define int long long
#define i128 __int128_t
#define all(vec) vec.begin(),vec.end()
#define vi vector<int>
#define vii vector<vector<int>>
using namespace std;
const int N = 5e5+10 ;
const int M = 1e3+10 ;
const int INF = 0x3f3f3f3f3f3f3f3f;
const int MOD1 = 1e9 + 7 ;
const int MOD2 = 998244353 ;
const double eps = 1e-9 ;
int gcd(int a, int b){ return b == 0 ? a : gcd(b, a%b); }
int lcm(int a, int b){ return a * b / gcd(a,b); }
int _ = 1 ;
int ans = 0 ;
int n , m, k, q ;
void solve(){
ans = 1 ;
cin >> n ;
vi a(n + 1,0) ;
vi b(n + 1,0) ;
bool f1 = true ;
for(int i = 1; i <= n ; ++ i){
cin >> a[i] ;
if(i >= 2 && a[i] != a[i-1]) f1 = false ;
b[i] = a[i] - a[i-1] ;
}
if(f1){
cout << 0 << endl ;
return ;
}
int t1 = 0 ;
for(int i = 2 ; i <= n ; ++ i){
t1 = gcd(t1, b[i]) ;
}
ans = abs(t1) ;
auto clac = [&]() -> void {
vi vec1 ;
for(int i = 1 ; i * i <= a[1] ; ++ i){
if(a[1] % i == 0){
vec1.push_back(i) ;
if(a[1] / i != i){
vec1.push_back(a[1] / i) ;
}
}
}
for(auto e : vec1){
vi vecte ;
bool f =true ;
int cnt = 0 ;
int la = 0 ;
for(int i = 2 ; i <= n ; ++ i){
if(b[i] % e != 0){
if(cnt == 0){
la = b[i] ;
f = true ;
}else if(cnt == 1){
if((b[i] + la) % e == 0){
f = true ;
}else{
f = false ;
}
}else{
f = false ;
break ;
}
cnt ++ ;
}
}
if(f) ans = max(ans,e) ;
}
};
clac() ;
reverse(a.begin() + 1, a.end()) ;
for(int i = 1; i <= n ; ++ i){
b[i] = a[i] - a[i-1] ;
}
clac() ;
cout << ans << endl ;
}
signed main(){
IOS ;
cin >> _ ;
while(_ --){
solve() ;
}
return 0;
}

Comments 1 条评论
test