2023.02.04 模拟赛小结
2023.02.04 模拟赛小结
更好的阅读体验戳此进入
赛时思路
T1
给定序列
emm 第一眼想到的是
后者整理得:
前者二维偏序可以优化到
Upd:也可以强行优化,发现
Code
#define _USE_MATH_DEFINES
#include <bits/stdc++.h>
#define PI M_PI
#define E M_E
#define npt nullptr
#define SON i->to
#define OPNEW void* operator new(size_t)
#define ROPNEW void* Edge::operator new(size_t){static Edge* P = ed; return P++;}
#define ROPNEW_NODE void* Node::operator new(size_t){static Node* P = nd; return P++;}
using namespace std;
mt19937 rnd(random_device{}());
int rndd(int l, int r){return rnd() % (r - l + 1) + l;}
bool rnddd(int x){return rndd(1, 100) <= x;}
typedef unsigned int uint;
typedef unsigned long long unll;
typedef long long ll;
typedef long double ld;
#define INF (0x3f3f3f3f)
template < typename T = int >
inline T read(void);
int N;
namespace Sub_1_2{
ll A[5100];
ll dp[5100][5100];
void Make(void){
memset(dp, 0xc0, sizeof dp);
for(int i = 1; i <= N; ++i)A[i] = read();
A[0] = -INF;
dp[1][0] = A[1], dp[1][1] = -1;
for(int i = 2; i <= N; ++i){
for(int j = 0; j <= i - 1; ++j)
if(A[i] >= A[i - 1 - j])
dp[i][0] = max(dp[i][0], dp[i - 1][j] + A[i]);
for(int j = 1; j <= i; ++j)
dp[i][j] = dp[i - 1][j - 1] + (((j - 1) * j) >> 1) - ((j * (j + 1)) >> 1);
}
ll ans(-INF);
for(int j = 0; j <= N; ++j)ans = max(ans, dp[N][j]);
printf("%lld\n", ans);
}
}
namespace Sub_3_4{
ll A[1100000];
void Make(void){
for(int i = 1; i <= N; ++i)A[i] = read();
}
}
int main(){
freopen("paint.in", "r", stdin);
freopen("paint.out", "w", stdout);
N = read();
if(N <= 10000)Sub_1_2::Make();
else exit(1);
fprintf(stderr, "Time: %.6lf\n", (double)clock() / CLOCKS_PER_SEC);
return 0;
}
/*
7
1 3 2 7 3 2 4
7
-3 -4 -2 -2 -6 -8 -1
*/
template < typename T >
inline T read(void){
T ret(0);
int flag(1);
char c = getchar();
while(c != '-' && !isdigit(c))c = getchar();
if(c == '-')flag = -1, c = getchar();
while(isdigit(c)){
ret *= 10;
ret += int(c - '0');
c = getchar();
}
ret *= flag;
return ret;
}
T2
给定字符串
基于 LG-P4324 [JSOI2016]扭动的回文串 修改的。
赛时一看默认这是 PAM 之类的东西(犇犇 @sssmzy 真的写了个 PAM)于是就跳了,写了个
正解真的巨简单
Code
#define _USE_MATH_DEFINES
#include <bits/stdc++.h>
#define PI M_PI
#define E M_E
#define npt nullptr
#define SON i->to
#define OPNEW void* operator new(size_t)
#define ROPNEW void* Edge::operator new(size_t){static Edge* P = ed; return P++;}
#define ROPNEW_NODE void* Node::operator new(size_t){static Node* P = nd; return P++;}
using namespace std;
mt19937 rnd(random_device{}());
int rndd(int l, int r){return rnd() % (r - l + 1) + l;}
bool rnddd(int x){return rndd(1, 100) <= x;}
typedef unsigned int uint;
typedef unsigned long long unll;
typedef long long ll;
typedef long double ld;
#define BASE (31)
template < typename T = int >
inline T read(void);
int N;
string S;
namespace Sub_1_2{
int ans(0);
unll pow_base[210];
unll hash[210], rhash[210];
void Cal(void){
hash[0] = rhash[N + 1] = 0;
for(int i = 1; i <= N; ++i)hash[i] = hash[i - 1] * BASE + S.at(i - 1);
for(int i = N; i >= 1; --i)rhash[i] = rhash[i + 1] * BASE + S.at(i - 1);
for(int l = 1; l <= N; ++l){
for(int r = l; r <= N; ++r){
unll hash1 = hash[r] - hash[l - 1] * pow_base[r - l + 1];
unll hash2 = rhash[l] - rhash[r + 1] * pow_base[r - l + 1];
if(hash1 == hash2)ans = max(ans, r - l + 1);
}
}
}
void Make(void){
pow_base[0] = 1;
for(int i = 1; i <= 205; ++i)pow_base[i] = pow_base[i - 1] * BASE;
Cal();
for(int i = 1; i <= N - 2; ++i){
char c = getchar(); while(!isalpha(c))c = getchar();
S.at(i) = c;
Cal();
}printf("%d\n", ans);
}
}
int main(){
freopen("str.in", "r", stdin);
freopen("str.out", "w", stdout);
N = read(); cin >> S;
if(N <= 600)Sub_1_2::Make();
else puts("qwq");
fprintf(stderr, "Time: %.6lf\n", (double)clock() / CLOCKS_PER_SEC);
return 0;
}
/*
6
ABAECB
B
C
D
E
*/
template < typename T >
inline T read(void){
T ret(0);
int flag(1);
char c = getchar();
while(c != '-' && !isdigit(c))c = getchar();
if(c == '-')flag = -1, c = getchar();
while(isdigit(c)){
ret *= 10;
ret += int(c - '0');
c = getchar();
}
ret *= flag;
return ret;
}
T3
还算是相对比较接近切掉的一道题。
给定序列
求操作
Tips:序列下标从
手画一下,例如
Code
#define _USE_MATH_DEFINES
#include <bits/stdc++.h>
#define PI M_PI
#define E M_E
#define npt nullptr
#define SON i->to
#define OPNEW void* operator new(size_t)
#define ROPNEW void* Edge::operator new(size_t){static Edge* P = ed; return P++;}
#define ROPNEW_NODE void* Node::operator new(size_t){static Node* P = nd; return P++;}
using namespace std;
mt19937 rnd(random_device{}());
int rndd(int l, int r){return rnd() % (r - l + 1) + l;}
bool rnddd(int x){return rndd(1, 100) <= x;}
typedef unsigned int uint;
typedef unsigned long long unll;
typedef long long ll;
typedef long double ld;
#define DFT (true)
#define IDFT (false)
#define MOD (998244353ll)
template < typename T = int >
inline T read(void);
int N, K; ll T;
int pos[410000];
ll g(3), inv_g;
ll A[410000];
ll qpow(ll a, ll b){
ll ret(1), mul(a);
while(b){
if(b & 1)ret = ret * mul % MOD;
b >>= 1;
mul = mul * mul % MOD;
}return ret;
}
class Polynomial{
private:
public:
int len;
ll poly[410000];
Polynomial(void){
len = 0;
memset(poly, 0, sizeof poly);
}
void Reverse(void){
for(int i = 0; i < len; ++i)
pos[i] = (pos[i >> 1] >> 1) | (i & 1 ? len >> 1 : 0);
for(int i = 0; i < len; ++i)if(i < pos[i])swap(poly[i], poly[pos[i]]);
}
void Shrink(void){
for(int i = N; i < len; ++i)(poly[i % N] += poly[i]) %= MOD, poly[i] = 0;
for(int i = 0; i < len; ++i)poly[i] %= 2;
len = min(len, N);
}
void NTT(bool pat){
Reverse();
for(int siz = 2; siz <= len; siz <<= 1){
ll gn = qpow(pat ? g : inv_g, (MOD - 1) / siz);
for(auto p = poly; p != poly + len; p += siz){
int mid = siz >> 1; ll g(1);
for(int i = 0; i < mid; ++i, (g *= gn) %= MOD){
auto tmp = g * p[i + mid] % MOD;
p[i + mid] = (p[i] - tmp + MOD) % MOD;
p[i] = (p[i] + tmp) % MOD;
}
}
}
if(!pat){
ll inv_len = qpow(len, MOD - 2);
for(int i = 0; i < len; ++i)(poly[i] *= inv_len) %= MOD;
Shrink();
}
}
void Print(void){
printf("Polynomial(len = %d): ", len);
for(int i = 0; i < len; ++i)printf("%lld ", poly[i]);
printf("\n");
}
};
Polynomial ret, mul;
void qpow(Polynomial* a, ll b){
for(int i = 0; i < ret.len; ++i)ret.poly[i] = 0;
ret.len = 1, ret.poly[0] = 1;
mul = *a;
while(b){
if(b & 1){
int base(1); while(base < ret.len + mul.len - 1)base <<= 1;
ret.len = mul.len = base;
ret.NTT(DFT), mul.NTT(DFT);
for(int i = 0; i < base; ++i)ret.poly[i] = ret.poly[i] * mul.poly[i] % MOD;
ret.NTT(IDFT), mul.NTT(IDFT);
}
b >>= 1;
int base(1); while(base < mul.len + mul.len - 1)base <<= 1;
mul.len = base;
mul.NTT(DFT);
for(int i = 0; i < base; ++i)mul.poly[i] = mul.poly[i] * mul.poly[i] % MOD;
mul.NTT(IDFT);
}
}
int main(){
freopen("xortwo.in", "r", stdin);
freopen("xortwo.out", "w", stdout);
inv_g = qpow(g, MOD - 2);
N = read(), K = read(); T = read < ll >();
Polynomial origin;
origin.len = K;
for(int i = 0; i < origin.len; ++i)origin.poly[i] = 1;
// {
// int base(1); while(base < origin.len)base <<= 1;
// origin.len = base;
// origin.Print();
// origin.NTT(DFT), origin.NTT(IDFT);
// origin.Print();
// base = (1); while(base < origin.len)base <<= 1;
// origin.len = base;
// origin.NTT(DFT), origin.NTT(IDFT);
// origin.Print();
// }
qpow(&origin, T);
basic_string < int > isTrue;
for(int i = 0; i < N; ++i)if(ret.poly[i])isTrue += i;
// ret.Print();
for(int i = 0; i < N; ++i)A[i] = read();
for(int i = 0; i < N; ++i){
ll val(0);
for(auto j : isTrue)val ^= A[(i + j) % N];
printf("%lld%c", val, i == N - 1 ? '\n' : ' ');
}
fprintf(stderr, "Time: %.6lf\n", (double)clock() / CLOCKS_PER_SEC);
return 0;
}
/*
5 3 1
3 0 2 1 2
5 3 2
3 0 2 1 2
5 3 15
3 0 2 1 2
11 5 1000000000000000000
2 2 4 5 9 1 5 7 7 1 8
*/
template < typename T >
inline T read(void){
T ret(0);
int flag(1);
char c = getchar();
while(c != '-' && !isdigit(c))c = getchar();
if(c == '-')flag = -1, c = getchar();
while(isdigit(c)){
ret *= 10;
ret += int(c - '0');
c = getchar();
}
ret *= flag;
return ret;
}
正解
T1
简单设一个
T2
就是个哈希,类比一下原题就行,分割成中间的回文串和左右相同的两串,中间回文串满足单调性,跑一下即可。
另外对于一般的哈希也是满足单调性的,枚举每一个中点然后取最大值并令其不降最终就是
T3
考虑最终将二进制拆位并 NTT 即可,此时就能几乎拿满了。对于过程中会发现有一些难以想到的性质,emm 大概就是能推成一个新的柿子,然后就能优化,emmmmmm 这个东西吧。。反正很奇怪就对了。
代码实现就先都咕着了。
UPD
update-2023_02_04 初稿
本文作者:tsawke
本文链接:https://www.cnblogs.com/tsawke/p/17124364.html
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步