2022.12.23 模拟赛小结
2022.12.23 模拟赛小结
更好的阅读体验戳此进入
赛时思路
T1
原题 CF1446C Xor Tree。
最开始以为是先建图然后固定住图之后删点,想了半天感觉差不多思路出来了,然后算了一遍样例才发现假掉了,删点之后边也会对应移动,这东西是动态变化的,一个来小时的思路全寄掉了,然后也就没什么想法了,最终
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(arr) void* Edge::operator new(size_t){static Edge* P = arr; 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[210000];
int ans(INT_MAX);
bitset < 12 > vis;
bitset < 12 > exist[12];
bool flag(true);
int cnt(0);
basic_string < int > cur;
struct Edge{
Edge* nxt;
int to;
OPNEW;
}ed[1100000];
ROPNEW(ed);
Edge* head[12];
void dfs_vis(int p, int fa = 0){
vis[p] = true, ++cnt;
for(auto i = head[p]; i; i = i->nxt){
if(SON == fa)continue;
if(vis[SON]){flag = false; return;}
dfs_vis(SON, p);
}
}
bool Check(void){
memset(head, 0, sizeof head);
for(int i = 0; i <= 11; ++i)exist[i].reset();
vis.reset();
int tot = cur.size();
if(tot <= 1)return true;
for(auto p : cur){
int mn(INT_MAX), mnp(-1);
for(auto q : cur)
if(q != p && (a[p] ^ a[q]) < mn)mn = a[p] ^ a[q], mnp = q;
if(exist[p][mnp])continue;
exist[p][mnp] = exist[mnp][p] = true;
head[p] = new Edge{head[p], mnp};
head[mnp] = new Edge{head[mnp], p};
}flag = true, cnt = 0; dfs_vis(cur.front());
return flag && cnt == tot;
}
void dfs(int p = 1){
if(p > N){
if(Check())ans = min(ans, N - (int)cur.size());
return;
}
dfs(p + 1);
cur += p;
dfs(p + 1);
cur.pop_back();
}
int main(){
freopen("star.in", "r", stdin);
freopen("star.out", "w", stdout);
N = read();
if(N > 10)printf("qwq\n"), exit(0);
for(int i = 1; i <= N; ++i)a[i] = read();
dfs();
printf("%d\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(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-P3747 [六省联考 2017] 相逢是问候。
cc0000 贴心地给了 exEular,但是依然没想出来,只能有一点思路,具体是在没搞出来。但是实际上好像难度也不算是太离谱,比较显然,不过细节比较多。
然后写了点简单的部分分,时间都在调 T3 所以也没去写后面的性质,最后
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(arr) void* Edge::operator new(size_t){static Edge* P = arr; 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 MOD P
template < typename T = int >
inline T read(void);
int N, M, P, C;
int a[51000];
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 SegTree{
private:
ll tr[210000 << 2];
#define LS (p << 1)
#define RS (LS | 1)
#define MID ((gl + gr) >> 1)
public:
void Pushup(int p){
tr[p] = (tr[LS] + tr[RS]) % MOD;
}
void Build(int p = 1, int gl = 1, int gr = N){
if(gl == gr)return tr[p] = a[gl] % MOD, void();
Build(LS, gl, MID), Build(RS, MID + 1, gr);
Pushup(p);
}
void Modify(int pos, int p = 1, int gl = 1, int gr = N){
if(gl == gr)return tr[p] = qpow(C, tr[p]), void();
if(pos <= MID)Modify(pos, LS, gl, MID);
else Modify(pos, RS, MID + 1, gr);
Pushup(p);
}
ll Query(int l, int r, int p = 1, int gl = 1, int gr = N){
if(l <= gl && gr <= r)return tr[p];
if(l > gr || r < gl)return 0;
return (Query(l, r, LS, gl, MID) + Query(l, r, RS, MID + 1, gr)) % MOD;
}
}st;
int main(){
freopen("candle.in", "r", stdin);
freopen("candle.out", "w", stdout);
N = read(), M = read(), P = read(), C = read();
for(int i = 1; i <= N; ++i)a[i] = read();
st.Build();
while(M--){
int opt = read();
if(opt == 0){
int l = read(), r = read();
for(int i = l; i <= r; ++i)st.Modify(i);
}else{
int l = read(), r = read();
printf("%lld\n", st.Query(l, r));
}
}
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;
}
T3
原题 CF802O April Fools' Problem (hard)。
正解确实没想到,不过一个比较显然的费用流应该不难想,因为确实很显然。。。
套个正常的模板 MCMF,额外建个边限制一下最大流为
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(arr) void* Edge::operator new(size_t){static Edge* P = arr; 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);
struct Edge{
Edge* nxt;
Edge* rev;
int to;
ll flow;
ll c;
OPNEW;
}ed[30000];
ROPNEW(ed);
Edge* head[2100];
const int S = 2001, RS = 2002, T = 2003, RT = 2004;
int N, K;
ll a[2100], b[2100];
Edge* edg[2100];
ll dis[2100];
ll cflow[2100];
bitset < 2100 > inq;
ll ans(0);
bool SPFA(void){
memset(dis, 0x3f, sizeof dis);
memset(edg, false, sizeof edg);
queue < int > cur;
dis[RS] = 0, cflow[RS] = 0x3f3f3f3f, inq[RS] = true;
cur.push(RS);
while(!cur.empty()){
// printf("searching %d\n", cur.front());
int p = cur.front(); cur.pop(); inq[p] = false;
for(auto i = head[p]; i; i = i->nxt){
if(i->flow <= 0 || dis[SON] <= dis[p] + i->c)continue;
dis[SON] = dis[p] + i->c, cflow[SON] = min(cflow[p], i->flow), edg[SON] = i;
if(!inq[SON])cur.push(SON), inq[SON] = true;
}
}return edg[RT];
}
void MCMF(void){
while(SPFA()){
ans += dis[RT] * cflow[RT];
for(int p = RT; p != RS; p = edg[p]->rev->to)
edg[p]->flow -= cflow[RT], edg[p]->rev->flow += cflow[RT];
}
}
void add(int s, int t, int flow, int c){
head[s] = new Edge{head[s], npt, t, flow, c};
head[t] = new Edge{head[t], npt, s, 0, -c};
head[s]->rev = head[t], head[t]->rev = head[s];
}
int main(){
freopen("letter.in", "r", stdin);
freopen("letter.out", "w", stdout);
N = read(), K = read();
for(int i = 1; i <= N; ++i)a[i] = read();
for(int i = 1; i <= N; ++i)b[i] = read();
add(RS, S, K, 0), add(T, RT, K, 0);
for(int i = 1; i <= N; ++i){
add(S, i, 1, a[i]), add(i, T, 1, b[i]);
if(i <= N - 1)add(i, i + 1, 0x3f3f3f3f >> 1, 0);
}while(SPFA())MCMF();
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(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;
}
正解
补题暂时咕掉了,laterrrr 回来补。
T1
Code
T2
Code
T3
Code
UPD
update-2022_12_24 初稿
本文作者:Tsawke
本文链接:https://www.cnblogs.com/tsawke/p/17032817.html
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
分类:
Exam
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步