2023.02.16 模拟赛小结
2023.02.16 模拟赛小结
更好的阅读体验戳此进入
赛时思路
T1
给定
一个显而易见的思路,用
(最后拿到了 ty > M ? M : ty
最开始写成
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;
template < typename T = int >
inline T read(void);
int N, M;
vector < vector < bool > > mp;
vector < vector < int > > sum;
vector < vector < bool > > mark;
vector < vector < int > > csum;
bool Check(int siz){
for(int i = 1; i <= N; ++i)
for(int j = 1; j <= M; ++j)
mark[i][j] = false, csum[i][j] = 0;
for(int i = siz + 1; i <= N - siz; ++i){
for(int j = siz + 1; j <= M - siz; ++j){
int sx = i - siz, sy = j - siz, tx = i + siz, ty = j + siz;
int rsum = sum[tx][ty] - sum[sx - 1][ty] - sum[tx][sy - 1] + sum[sx - 1][sy - 1];
int esum = ((siz << 1) | 1) * ((siz << 1) | 1);
if(esum == rsum)mark[i][j] = true;
}
}
for(int i = 1; i <= N; ++i)
for(int j = 1; j <= M; ++j)
csum[i][j] = csum[i - 1][j] + csum[i][j - 1] - csum[i - 1][j - 1] + mark[i][j];
for(int i = 1; i <= N; ++i)
for(int j = 1; j <= M; ++j){
int sx = i - siz, sy = j - siz, tx = i + siz, ty = j + siz;
if(mp[i][j] && !(csum[tx > N ? N : tx][ty > M ? M : ty] - csum[tx > N ? N : tx][sy - 1 < 0 ? 0 : sy - 1] - csum[sx - 1 < 0 ? 0 : sx - 1][ty > M ? M : ty] + csum[sx - 1 <= 0 ? 0 : sx - 1][sy - 1 < 0 ? 0 : sy - 1]))
return false;
}
return true;
}
int main(){
freopen("yawn.in", "r", stdin);
freopen("yawn.out", "w", stdout);
N = read(), M = read();
for(int i = 0; i <= N; ++i){
mark.emplace_back(vector < bool >());
csum.emplace_back(vector < int >());
for(int j = 0; j <= M; ++j)
// mark[i] += false, csum[i] += 0;
mark[i].emplace_back(false), csum[i].emplace_back(0);
}
// mp += vector < bool >();
mp.emplace_back(vector < bool >());
// vis += vector < bool >();
for(int i = 0; i <= M; ++i)mp[0].emplace_back(false);//, vis[0] += false;
for(int i = 1; i <= N; ++i){
mp.emplace_back(vector < bool >());// += vector < bool >();
// vis += vector < bool >();
// mp[i] += false;//, vis[i] += false;
mp[i].emplace_back(false);
for(int j = 1; j <= M; ++j){
char c = getchar(); while(c != '.' && c != 'X')c = getchar();
// mp[i] += c == '.' ? false : true;
mp[i].emplace_back(c == '.' ? false : true);
// vis[i] += c == '.' ? false : true;
}
}
// sum += vector < int >();
sum.emplace_back(vector < int >());
for(int i = 0; i <= M; ++i)sum[0].emplace_back(0); //sum[0] += 0;
for(int i = 1; i <= N; ++i){
// sum += vector < int >();
sum.emplace_back(vector < int >());
// sum[i] += 0;
sum[i].emplace_back(0);
for(int j = 1; j <= M; ++j)
// sum[i] += sum[i - 1][j] + sum[i][j - 1] - sum[i - 1][j - 1] + mp[i][j];
sum[i].emplace_back(sum[i - 1][j] + sum[i][j - 1] - sum[i - 1][j - 1] + mp[i][j]);
}
printf("Checking 50 %d\n\n\n\n\n", Check(50) ? 1 : 0);
int l = 1, r = min((N - 1) >> 1, (M - 1) >> 1), ans = -1;
while(l <= r){
int mid = (l + r) >> 1;
if(Check(mid))ans = mid, l = mid + 1;
else r = mid - 1;
}
if(!~ans){
printf("0\n");
for(int i = 1; i <= N; ++i)
for(int j = 1; j <= M; ++j)
printf("%c%s", mp[i][j] ? 'X' : '.', j == M ? "\n" : "");
exit(0);
}
int siz = ans;
for(int i = 1; i <= N; ++i)
for(int j = 1; j <= M; ++j)
mark[i][j] = false;
for(int i = siz + 1; i <= N - siz; ++i){
for(int j = siz + 1; j <= M - siz; ++j){
int sx = i - siz, sy = j - siz, tx = i + siz, ty = j + siz;
int rsum = sum[tx][ty] - sum[sx - 1][ty] - sum[tx][sy - 1] + sum[sx - 1][sy - 1];
int esum = ((siz << 1) | 1) * ((siz << 1) | 1);
if(esum == rsum)mark[i][j] = true;
}
}
printf("%d\n", ans);
for(int i = 1; i <= N; ++i)
for(int j = 1; j <= M; ++j)
printf("%c%s", mark[i][j] ? 'X' : '.', j == M ? "\n" : "");
fprintf(stderr, "Time: %.6lf\n", (double)clock() / CLOCKS_PER_SEC);
return 0;
}
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
给定序列,每次从序列中取数直至取空,每次取
赛时思路是考虑记录
Code
/*
2
5
7 10 4 9 4
3
2 1 7
3
7
22 34 48 12 48 37 27
10
19 37 37 51 40 87 25 28 81 26
9
51 60 21 52 25 46 40 37 3
*/
#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;
template < typename T = int >
inline T read(void);
int N;
int A[1100000];
int val[1100000];
int pri[1100000];
int pre[1100000], nxt[1100000];
bitset < 1100000 > vis;
ll ans(0);
priority_queue < pair < int, int >, vector < pair < int, int > >, less < pair < int, int > > > cur;
int main(){
freopen("sum.in", "r", stdin);
freopen("sum.out", "w", stdout);
int T = read();
while(T--){
for(int i = 0; i <= N + 1; ++i)vis[i] = false;
N = read();
A[0] = A[N + 1] = 0; pre[0] = 0, nxt[N + 1] = N + 1, pre[N + 1] = N, nxt[0] = 1;
val[0] = val[N + 1] = pri[0] = pri[N + 1] = 0, ans = 0;
for(int i = 1; i <= N; ++i)A[i] = read();
for(int i = 1; i <= N; ++i)pre[i] = i - 1, nxt[i] = i + 1;
for(int i = 1; i <= N; ++i)val[i] = min(A[pre[i]], A[nxt[i]]);
for(int i = 1; i <= N; ++i)pri[i] = val[i] - (val[pre[i]] - min(A[pre[pre[i]]], A[nxt[i]])) - (val[nxt[i]] - min(A[nxt[nxt[i]]], A[pre[i]]));
for(int i = 1; i <= N; ++i)cur.push({pri[i], i});
while(!cur.empty()){
auto tp = cur.top(); cur.pop();
int idx = tp.second;
if(tp.first != pri[idx] || vis[idx])continue;
ans += val[idx], vis[idx] = true;
val[pre[idx]] = min(A[pre[pre[idx]]], A[nxt[idx]]);
val[nxt[idx]] = min(A[nxt[nxt[idx]]], A[pre[idx]]);
pri[pre[idx]] = val[pre[idx]] - (val[pre[pre[idx]]] - min(A[pre[pre[pre[idx]]]], A[nxt[idx]])) - (val[nxt[idx]] - min(A[nxt[nxt[idx]]], A[pre[pre[idx]]]));
pri[nxt[idx]] = val[nxt[idx]] - (val[pre[idx]] - min(A[pre[pre[idx]]], A[nxt[nxt[idx]]])) - (val[nxt[nxt[idx]]] - min(A[nxt[nxt[nxt[idx]]]], A[pre[idx]]));
cur.push({pri[pre[idx]], pre[idx]}), cur.push({pri[nxt[idx]], nxt[idx]});
nxt[pre[idx]] = nxt[idx], pre[nxt[idx]] = pre[idx];
int i = pre[pre[idx]];
pri[i] = val[i] - (val[pre[i]] - min(A[pre[pre[i]]], A[nxt[i]])) - (val[nxt[i]] - min(A[nxt[nxt[i]]], A[pre[i]]));
cur.push({pri[i], i});
i = nxt[nxt[idx]];
pri[i] = val[i] - (val[pre[i]] - min(A[pre[pre[i]]], A[nxt[i]])) - (val[nxt[i]] - min(A[nxt[nxt[i]]], A[pre[i]]));
cur.push({pri[i], i});
}printf("%lld\n", ans);
}
fprintf(stderr, "Time: %.6lf\n", (double)clock() / CLOCKS_PER_SEC);
return 0;
}
template < typename T >
inline T read(void){
T ret(0);
// int flag(1);
char c = getchar();
while(!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
给定序列
给定
赛时写了个暴力,就不挂 Code 了。
T4
奇怪题,没写。
正解
T2
考虑三个数
T3
首先说一下 @sssmzy 的高妙思路(确实巧妙,必须 %%%%%%%
考虑下取整的意义就是正常的除法之后再取整,于是直接考虑我们不考虑下取整,认为其为标准除法,然后则可以在线段树上合并,最后再取整即可。有一个问题就是这个东西并不是适用于所有,本题适用应该是因为对于 long double
,会 long double
真的很慢。(@sssmzy 就是因为 long double
而
UPD
update-2023_02_16 初稿
本文作者:tsawke
本文链接:https://www.cnblogs.com/tsawke/p/17180234.html
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步