2022 Jiangsu Collegiate Programming Contest
A. PENTA KILL!
把每个一个人的击杀序列分开,判断是否有连续五个不同的击杀就好
#include<bits/stdc++.h>
using namespace std;
map<string , vector<string> > st;
int32_t main(){
int n;
cin >> n;
string a , b;
for( int i = 1 ; i <= n ; i ++ ){
cin >> a >> b;
st[a].push_back(b);
}
for( auto [t , e] : st ){
for( int i = 4 ; i < e.size() ; i ++ ){
set<string> s;
s.insert( e[i] );
s.insert( e[i-1] );
s.insert( e[i-2] );
s.insert( e[i-3] );
s.insert( e[i-4] );
if( s.size() == 5 ){
cout << "PENTA KILL!";
return 0;
}
}
}
cout << "SAD:(\n";
}
C. Jump and Treasure
一个的单调队列优化dp
对于第x关 ,[1,n]
中一共有m=n/x
个可以到达的柱子,然后f[i]
表示到达i*x
所可以获得的最多的分数,则转移方程就是f[i]=max(f[j])+a[i*x],(i-j)*x<p
,对于这种类型的dp,用一个单调队列维护一下最大值就好了
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N = 2e6+5;
int read() {
int x = 0, f = 1, ch = getchar();
while ((ch < '0' || ch > '9') && ch != '-') ch = getchar();
if (ch == '-') f = -1, ch = getchar();
while (ch >= '0' && ch <= '9') x = (x << 3) + (x << 1) + ch - '0', ch = getchar();
return x * f;
}
int a[N] , f[N];
int32_t main() {
int n = read() , q = read() , p = read();
for( int i = 1 ; i <= n ; i ++ ) a[i] = read();
for( int x , m ; q ; q -- ){
x = read() , m = n / x;
if( x > p ){
cout << "Noob\n";
continue;
}
priority_queue< pair<int,int> > pq;
pq.push( { 0 , 0 } );
for( int i = 1 ; i <= m ; i ++ ){
while( (i - pq.top().second) * x > p ) pq.pop();
f[i] = pq.top().first + a[i*x];
pq.push( { f[i] , i } );
}
while( n + 1 - pq.top().second * x > p ) pq.pop();
cout << pq.top().first << "\n";
}
return 0;
}
I. Cutting Suffix
这里的做法就是,把所有开头相同的后缀都放在一个集合中,这样两个集合中任意两个的LCP都是0。
但是有一种情况需要特判就是所有的开头都相同,这时就不得不把一个后缀放在另一个集合中,显然把最后一个放过去是最有解,只是一共有n-1
个LCP,每一个LCP都是1
#include<bits/stdc++.h>
using namespace std;
int32_t main() {
string s;
cin >> s;
int f = 1;
for( int i = 1 ; i < s.size() && f ; i ++ )
if( s[i] != s[0] ) f = 0;
if( f ) cout << s.size()-1;
else cout << 0;
return 0;
}
J. Balanced Tree
f[i]
表示i
个节点的super balanced tree
的种类数,显然可以得到一个递推公示
然后可以用记忆化搜索来解这道题,只不过这样会消耗大量的空间,而不记忆化又会消耗大量的时间。但是通过在本地打表发现,当i
比较大时(比如\(i>2^{20}\))的时候,只有当i
在2的整次幂附近时才有值(距离不大于5),其他的情况都是0,所以可以把2的整次幂附近的值算出来打一个表就好了
#include<bits/stdc++.h>
#define int unsigned long long
using namespace std;
const int N = 5e6+5;
int g[N];
map<int, int> ans;
int read() {
int x = 0, ch = getchar();
while ((ch < '0' || ch > '9') && ch != '-') ch = getchar();
while (ch >= '0' && ch <= '9') x = (x << 3) + (x << 1) + ch - '0', ch = getchar();
return x;
}
#define lowbit(x) ( x & -x )
int f( int x ){
if( x > (1ull<<20) ){
if (ans.count(x)) return ans[x];
return 0;
}
if( g[x] ) return g[x];
if( x & 1 ) return g[x] = f((x-1)/2 ) * f((x-1)>>1 );
else return g[x] = f((x-1)/2) * f((x-1)/2+1) * 2;
}
void solve(){
int n = read();
cout << f(n) << "\n";
return;
}
int32_t main() {
vector<pair<int, int> >dabiao = {{1048572ull,9007199254740992ull},
{1048573ull,68719476736ull},
{1048574ull,524288ull},
{1048575ull,1ull},
{1048576ull,1048576ull},
{1048577ull,274877906944ull},
{1048578ull,72057594037927936ull},
{2097148ull,72057594037927936ull},
{2097149ull,274877906944ull},
{2097150ull,1048576ull},
{2097151ull,1ull},
{2097152ull,2097152ull},
{2097153ull,1099511627776ull},
{2097154ull,576460752303423488ull},
{4194300ull,576460752303423488ull},
{4194301ull,1099511627776ull},
{4194302ull,2097152ull},
{4194303ull,1ull},
{4194304ull,4194304ull},
{4194305ull,4398046511104ull},
{4194306ull,4611686018427387904ull},
{8388604ull,4611686018427387904ull},
{8388605ull,4398046511104ull},
{8388606ull,4194304ull},
{8388607ull,1ull},
{8388608ull,8388608ull},
{8388609ull,17592186044416ull},
{16777213ull,17592186044416ull},
{16777214ull,8388608ull},
{16777215ull,1ull},
{16777216ull,16777216ull},
{16777217ull,70368744177664ull},
{33554429ull,70368744177664ull},
{33554430ull,16777216ull},
{33554431ull,1ull},
{33554432ull,33554432ull},
{33554433ull,281474976710656ull},
{67108861ull,281474976710656ull},
{67108862ull,33554432ull},
{67108863ull,1ull},
{67108864ull,67108864ull},
{67108865ull,1125899906842624ull},
{134217725ull,1125899906842624ull},
{134217726ull,67108864ull},
{134217727ull,1ull},
{134217728ull,134217728ull},
{134217729ull,4503599627370496ull},
{268435453ull,4503599627370496ull},
{268435454ull,134217728ull},
{268435455ull,1ull},
{268435456ull,268435456ull},
{268435457ull,18014398509481984ull},
{536870909ull,18014398509481984ull},
{536870910ull,268435456ull},
{536870911ull,1ull},
{536870912ull,536870912ull},
{536870913ull,72057594037927936ull},
{1073741821ull,72057594037927936ull},
{1073741822ull,536870912ull},
{1073741823ull,1ull},
{1073741824ull,1073741824ull},
{1073741825ull,288230376151711744ull},
{2147483645ull,288230376151711744ull},
{2147483646ull,1073741824ull},
{2147483647ull,1ull},
{2147483648ull,2147483648ull},
{2147483649ull,1152921504606846976ull},
{4294967293ull,1152921504606846976ull},
{4294967294ull,2147483648ull},
{4294967295ull,1ull},
{4294967296ull,4294967296ull},
{4294967297ull,4611686018427387904ull},
{8589934589ull,4611686018427387904ull},
{8589934590ull,4294967296ull},
{8589934591ull,1ull},
{8589934592ull,8589934592ull},
{17179869182ull,8589934592ull},
{17179869183ull,1ull},
{17179869184ull,17179869184ull},
{34359738366ull,17179869184ull},
{34359738367ull,1ull},
{34359738368ull,34359738368ull},
{68719476734ull,34359738368ull},
{68719476735ull,1ull},
{68719476736ull,68719476736ull},
{137438953470ull,68719476736ull},
{137438953471ull,1ull},
{137438953472ull,137438953472ull},
{274877906942ull,137438953472ull},
{274877906943ull,1ull},
{274877906944ull,274877906944ull},
{549755813886ull,274877906944ull},
{549755813887ull,1ull},
{549755813888ull,549755813888ull},
{1099511627774ull,549755813888ull},
{1099511627775ull,1ull},
{1099511627776ull,1099511627776ull},
{2199023255550ull,1099511627776ull},
{2199023255551ull,1ull},
{2199023255552ull,2199023255552ull},
{4398046511102ull,2199023255552ull},
{4398046511103ull,1ull},
{4398046511104ull,4398046511104ull},
{8796093022206ull,4398046511104ull},
{8796093022207ull,1ull},
{8796093022208ull,8796093022208ull},
{17592186044414ull,8796093022208ull},
{17592186044415ull,1ull},
{17592186044416ull,17592186044416ull},
{35184372088830ull,17592186044416ull},
{35184372088831ull,1ull},
{35184372088832ull,35184372088832ull},
{70368744177662ull,35184372088832ull},
{70368744177663ull,1ull},
{70368744177664ull,70368744177664ull},
{140737488355326ull,70368744177664ull},
{140737488355327ull,1ull},
{140737488355328ull,140737488355328ull},
{281474976710654ull,140737488355328ull},
{281474976710655ull,1ull},
{281474976710656ull,281474976710656ull},
{562949953421310ull,281474976710656ull},
{562949953421311ull,1ull},
{562949953421312ull,562949953421312ull},
{1125899906842622ull,562949953421312ull},
{1125899906842623ull,1ull},
{1125899906842624ull,1125899906842624ull},
{2251799813685246ull,1125899906842624ull},
{2251799813685247ull,1ull},
{2251799813685248ull,2251799813685248ull},
{4503599627370494ull,2251799813685248ull},
{4503599627370495ull,1ull},
{4503599627370496ull,4503599627370496ull},
{9007199254740990ull,4503599627370496ull},
{9007199254740991ull,1ull},
{9007199254740992ull,9007199254740992ull},
{18014398509481982ull,9007199254740992ull},
{18014398509481983ull,1ull},
{18014398509481984ull,18014398509481984ull},
{36028797018963966ull,18014398509481984ull},
{36028797018963967ull,1ull},
{36028797018963968ull,36028797018963968ull},
{72057594037927934ull,36028797018963968ull},
{72057594037927935ull,1ull},
{72057594037927936ull,72057594037927936ull},
{144115188075855870ull,72057594037927936ull},
{144115188075855871ull,1ull},
{144115188075855872ull,144115188075855872ull},
{288230376151711742ull,144115188075855872ull},
{288230376151711743ull,1ull},
{288230376151711744ull,288230376151711744ull},
{576460752303423486ull,288230376151711744ull},
{576460752303423487ull,1ull},
{576460752303423488ull,576460752303423488ull},
{1152921504606846974ull,576460752303423488ull},
{1152921504606846975ull,1ull},
{1152921504606846976ull,1152921504606846976ull},
{2305843009213693950ull,1152921504606846976ull},
{2305843009213693951ull,1ull},
{2305843009213693952ull,2305843009213693952ull},
{4611686018427387902ull,2305843009213693952ull},
{4611686018427387903ull,1ull},
{4611686018427387904ull,4611686018427387904ull},
{9223372036854775806ull,4611686018427387904ull},
{9223372036854775807ull,1ull},
{9223372036854775808ull,9223372036854775808ull},
{18446744073709551615ull,1ull},
{18446744073709551614ull,9223372036854775808ull}};
for (const auto &i : dabiao) {
ans.emplace(i);
}
g[0] = g[1] = 1;
for( int T = read() ; T ; T -- )
solve();
}
K. aaaaaaaaaaA heH heH nuN
首先输出一个前缀 nunhehhe
,然后再输出足够数量的a
在\(x\)个a
前面插入一个h
此时就会得到\(2^x-1\)个合法子序列
所以我们不断的找出再当前的情况下\(2^x-1\le n\)的\(x\)的最大值,再从后向前\(x\)个a
前插入一个h
,然后\(n\)减去\(2^x-1\),不断操作就好。
那么多少是足够数量的a
呢,简单一点就是\(\log_2^n\)个就够用了
然后求\(x\)的过程用二分答案,然后我们并不真的插入,而是先算出每一个a
前面应该有多少h
即可
#include<bits/stdc++.h>
using namespace std;
int read() {
int x = 0, f = 1, ch = getchar();
while ((ch < '0' || ch > '9') && ch != '-') ch = getchar();
if (ch == '-') f = -1, ch = getchar();
while (ch >= '0' && ch <= '9') x = (x << 3) + (x << 1) + ch - '0', ch = getchar();
return x * f;
}
void solve(){
int n = read();
cout << "nunhehhe";
if( !n ) return cout << "\n" , void();
int cnt = log2(n) + 1;
vector<int> ca(cnt+5);
while( n ){
int l = 1 , r = cnt , mid , res;
while( l <= r ){
mid = ( l + r ) >> 1;
if( ( 1ll << mid ) - 1 <= n ) res = mid , l = mid + 1;
else r = mid - 1;
}
ca[ cnt - res + 1 ] ++;
n -= ( 1ll << res ) - 1;
}
for( int i = 1 ; i <= cnt ; i ++ ){
for( int j = 1 ; j <= ca[i] ; j ++ )
cout << 'h';
cout << 'a';
}
cout << "\n";
return;
}
int32_t main() {
for( int T = read() ; T ; T -- )
solve();
return 0;
}
L. Collecting Diamonds
首先可以换个思路来理解题目。
如果B
是在偶数位置,就要删掉两侧的AC
,否则就是删掉B
。
然后可以知道的是,删掉AC
不会影响后面B
的奇偶,而删掉B
会影响后面B
的奇偶。
对于一个B
,如果两侧有多个AC
的话,就算当前的B
是偶数,但是删掉一个后也会变成奇数,所以如果先继续删,就要删除当前B
前面的任意一个B
才可以,然后不断的反复操作直到删完。
所以对于一个B
想知道他可以删掉多少个AC
,就要统计一下之前有多少个可以被删除掉的B
。
#include<bits/stdc++.h>
using namespace std;
int32_t main() {
string s;
cin >> s;
int n = s.size();
s = " " + s;
vector<pair<int,int>> p;
for( int i = 1 ; i <= n ; i ++ ){
if( s[i] != 'B' ) continue;
int t=0;
while( i-t-1 >= 1 && i+t+1 <= n && s[i-t-1] == 'A' && s[i+t+1] == 'C' ) t++;
if( t ) p.push_back( { i&1 , t } ); // 储存每一个 B d 位置的奇偶,和两侧有多少对 AC
}
int res = 0 , cnt = 0;// cnt : 已经删除了多少 B
for( auto [ odd, num ] : p ){
if( !cnt ){ // 在这之前还没有删除一个 b
if( odd ) res ++ , cnt ++; //如果 B 在奇数位,就只能把当前的位置 B 删掉
else {
if( num == 1 ) res ++ ;// 如果两侧只有一对 AC
else res += 2 , cnt ++;// 先删掉一对 AC,再删掉一个 B
}
}
else res += min( num , ( odd == 0 ) + cnt + 1 ) , cnt ++;
// 如果 B 当前是偶数就先删掉AC,如果不是等前面删掉一个 B 后再删掉 AC , 最后删掉 B
}
cout << res << "\n";
return 0;
}