NOIP 模拟赛 5
NOIP 模拟赛总结
NOIP 模拟赛 5
挂分啦
T1 家具运输
简单签到题,一眼二分答案。
点击查看代码
#include<bits/stdc++.h>
#define int long long
#define Blue_Archive return 0
#define con putchar_unlocked(' ')
#define ent putchar_unlocked('\n')
using namespace std;
constexpr int N = 2e3 + 7;
constexpr int INF = 1e18;
int n;
int K;
int sum;
int a[N];
bitset<N> vis;
inline int read()
{
int x = 0,f = 1;
int c = getchar_unlocked();
while(c < '0' || c > '9') f = (c == '-' ? -1 : f),c = getchar_unlocked();
while(c >= '0' && c <= '9') x = (x << 1) + (x << 3) + (c ^ 48),c = getchar_unlocked();
return x * f;
}
inline void write(int x)
{
if(x < 0) putchar_unlocked('-'),x = -x;
if(x > 9) write(x / 10);
putchar_unlocked(x % 10 + '0');
}
inline bool check(int op)
{
int tot = 0;
vis.reset();
for(int i = 1,res;i <= K;i ++)
{
res = op;
for(int j = 1;j <= n;j ++)
{
if(vis[j] || a[j] > res) continue;
res -= a[j];
tot ++;
vis[j] = 1;
}
}
return (tot == n);
}
signed main()
{
freopen("trans.in","r",stdin);freopen("trans.out","w",stdout);
// freopen("data.in","r",stdin);freopen("data.out","w",stdout);
n = read();
K = read();
for(int i = 1;i <= n;i ++)
{
a[i] = read();
sum += a[i];
}
sort(a + 1,a + n + 1,[](int a,int b){return a > b;});
int l = sum / K,r = sum,mid,res = -1;
while(l <= r)
{
mid = (l + r) >> 1;
if(check(mid)) r = mid - 1,res = mid;
else l = mid + 1;
}
write(res);ent;
Blue_Archive;
}
T2 取石子
神秘博弈论。
发现与二进制有关,要满足进行操作后使对方陷入无解的境地。
然后狂找性质不止。
点击查看代码
#include<bits/stdc++.h>
#define int long long
#define Blue_Archive return 0
#define con putchar_unlocked(' ')
#define ent putchar_unlocked('\n')
using namespace std;
constexpr int N = 5e4 + 7;
constexpr int M = 2e6 + 7;
constexpr int INF = 1e18;
int n;
int K;
int sum;
int a[N];
bool flag;
inline int read()
{
int x = 0,f = 1;
int c = getchar_unlocked();
while(c < '0' || c > '9') f = (c == '-' ? -1 : f),c = getchar_unlocked();
while(c >= '0' && c <= '9') x = (x << 1) + (x << 3) + (c ^ 48),c = getchar_unlocked();
return x * f;
}
inline void write(int x)
{
if(x < 0) putchar_unlocked('-'),x = -x;
if(x > 9) write(x / 10);
putchar_unlocked(x % 10 + '0');
}
signed main()
{
freopen("nim.in","r",stdin);freopen("nim.out","w",stdout);
// freopen("data.in","r",stdin);freopen("data.out","w",stdout);
n = read();
K = read();
for(int i = 1;i <= n;i ++)
{
a[i] = read();
sum ^= a[i];
}
for(int i = 1;i <= n;i ++)
{
for(int j = 1,now = 0,op;;j <<= 1)
{
if(now + j > a[i] || now + j > K) break;
op = a[i] - now; // 还剩这些
if(((sum ^ a[i] ^ op) & j) && ((sum ^ (op - j) ^ a[i]) & (j - 1)) == 0) // ((sum ^ (op - j) ^ a[i]) & (j - 1)) == 0 指让变化之后其他位的均为 0,使对方无解。
{
if(!flag)
{
write(1);ent;
flag = 1;
}
now += j;
write(i),con,write(now),ent;
}
}
}
if(!flag) write(0),ent;
Blue_Archive;
}
T3:均衡区间
只会 \(O(n ^ 2)\) 暴力qwq,SAM 场上根本手摸不出来qwq
发现不需要用 SA or SAM,直接在 fail 树上做树形 DP 即可。
点击查看代码
#include<bits/stdc++.h>
#define int long long
#define add(u,v) to[++ tot] = v,nxt[tot] = h[u],h[u] = tot
#define ull unsigned long long
#define Blue_Archive return 0
#define con putchar_unlocked(' ')
#define ent putchar_unlocked('\n')
using namespace std;
constexpr int N = 1e6 + 7;
constexpr int M = 1e6 + 7;
constexpr int INF = 1e18;
constexpr int mod = 998244353;
int n;
int K;
int ans;
int res;
int tot;
int a[N];
int h[N];
int to[M];
int nxt[M];
int fac[N];
int inv[N];
int siz[N];
int qnxt[N];
string s;
inline int qpow(int a,int b)
{
int res = 1;
while(b)
{
if(b & 1) res = res * a % mod;
a = a * a % mod;
b >>= 1;
}
return res;
}
inline void init()
{
fac[0] = inv[0] = 1;
for(int i = 1;i < N;i ++)
{
fac[i] = fac[i - 1] * i % mod;
inv[i] = qpow(fac[i],mod - 2);
}
}
inline int C(int n,int m)
{
if(n < m) return 0;
return fac[n] * inv[n - m] % mod * inv[m] % mod;
}
int op = 0;
inline void dfs(int x,int dep)
{
siz[x] = 1;
for(int i = h[x];i;i = nxt[i])
{
dfs(to[i],dep + 1);
siz[x] += siz[to[i]];
a[x] = ((a[x] - C(siz[to[i]],K) * dep % mod * dep % mod + a[to[i]]) % mod + mod) % mod;
}
a[x] = (a[x] + dep * dep % mod * C(siz[x],K) % mod) % mod;
}
signed main()
{
freopen("string.in","r",stdin);freopen("string.out","w",stdout);
// freopen("data.in","r",stdin);freopen("data.out","w",stdout);
ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
cin >> K;
cin >> s;
n = s.length();
s = ' ' + s;
init();
add(0,1);
for(int i = 2,j = 0;i <= n;i ++)
{
while(j && s[i] != s[j + 1]) j = qnxt[j];
if(s[i] == s[j + 1]) j ++;
qnxt[i] = j;
add(qnxt[i],i);
}
dfs(0,1);
ans = a[0];
cout << ans << '\n';
Blue_Archive;
}
T4:蚂蚁搬家
简单题,赛时因为线段树写假了 + 多开了 O(n) 个 set,导致 MLE。
进食后人,laz 标记千万不要忘记下放,痛挂 100 pts。qwq
点击查看代码
#include<bits/stdc++.h>
// #define int long long
#define ull unsigned long long
#define lid (id << 1)
#define rid (id << 1 | 1)
#define add(u,v) to[++ tot] = v,nxt[tot] = h[u],h[u] = tot
#define Blue_Archive return 0
#define con putchar_unlocked(' ')
#define ent putchar_unlocked('\n')
using namespace std;
constexpr int N = 1e6 + 7;
constexpr int M = 2e6 + 7;
constexpr int INF = 1e9;
int n;
int tot;
int tim;
int a[N];
int h[N];
int to[M];
int rk[N];
int fa[N];
int nxt[M];
int dep[N];
int son[N];
int siz[N];
int dfn[N];
int top[N];
unordered_map<ull,int> mp;
struct miku
{
int mn,id;
int laz;
ull bel,laz1,laz2;
}tr[N << 2];
struct mika
{
int u,v;
ull hx;
}q[N];
inline int read()
{
int x = 0,f = 1;
int c = getchar_unlocked();
while(c < '0' || c > '9') f = (c == '-' ? -1 : f),c = getchar_unlocked();
while(c >= '0' && c <= '9') x = (x << 1) + (x << 3) + (c ^ 48),c = getchar_unlocked();
return x * f;
}
inline void write(int x)
{
if(x < 0) putchar_unlocked('-'),x = -x;
if(x > 9) write(x / 10);
putchar_unlocked(x % 10 + '0');
}
inline void dfs1(int x,int f)
{
dep[x] = dep[f] + 1;
fa[x] = f;
siz[x] = 1;
for(int i = h[x];i;i = nxt[i])
{
if(to[i] == f) continue;
dfs1(to[i],x);
siz[x] += siz[to[i]];
if(siz[to[i]] > siz[son[x]]) son[x] = to[i];
}
}
inline void dfs2(int x,int tp)
{
top[x] = tp;
dfn[x] = ++ tim;
if(son[x]) dfs2(son[x],tp);
for(int i = h[x];i;i = nxt[i])
{
if(to[i] == son[x] || to[i] == fa[x]) continue;
dfs2(to[i],to[i]);
}
}
inline void pushup(int id)
{
tr[id].mn = min(tr[lid].mn,tr[rid].mn);
tr[id].id = (tr[lid].mn == tr[id].mn) ? tr[lid].id : tr[rid].id;
}
inline void change(int id,int cnt,int val)
{
tr[id].mn += cnt;
tr[id].laz += cnt;
tr[id].bel ^= val;
if(cnt > 0) tr[id].laz1 ^= val;
else tr[id].laz2 ^= val;
}
inline void pushdown(int id)
{
if(!tr[id].laz) return;
if(tr[id].laz > 0)
{
change(lid,tr[id].laz,tr[id].laz1);
change(rid,tr[id].laz,tr[id].laz1);
tr[id].laz1 = 0;
}
else
{
change(lid,tr[id].laz,tr[id].laz2);
change(rid,tr[id].laz,tr[id].laz2);
tr[id].laz2 = 0;
}
tr[id].laz = 0;
}
inline void build(int id,int l,int r)
{
if(l == r) return void(tr[id].id = l);
int mid = (l + r) >> 1;
build(lid,l,mid);
build(rid,mid + 1,r);
pushup(id);
}
inline void update(int id,int l,int r,int L,int R,int val,ull uid)
{
if(L > r || l > R || L > R) return;
if(L <= l && r <= R)
{
change(id,val,uid);
return;
}
int mid = (l + r) >> 1;
pushdown(id);
update(lid,l,mid,L,R,val,uid);
update(rid,mid + 1,r,L,R,val,uid);
pushup(id);
}
inline ull query(int id,int l,int r,int pos)
{
if(l == r) return tr[id].bel;
int mid = (l + r) >> 1;
pushdown(id);
if(pos <= mid) return query(lid,l,mid,pos);
else return query(rid,mid + 1,r,pos);
pushup(id);
}
inline int query_mn(int id,int l,int r,int pos)
{
if(l == r) return tr[id].mn;
int mid = (l + r) >> 1;
pushdown(id);
if(pos <= mid) return query_mn(lid,l,mid,pos);
else return query_mn(rid,mid + 1,r,pos);
}
inline void build2(int id,int l,int r)
{
if(l == r) return;
if(tr[id].mn == 0) tr[id].mn = INF;
pushdown(id);
int mid = (l + r) >> 1;
build2(lid,l,mid);
build2(rid,mid + 1,r);
pushup(id);
}
inline void path_add(int u,int v,ull id)
{
while(top[u] != top[v])
{
if(dep[top[u]] < dep[top[v]]) swap(u,v);
update(1,1,n,dfn[top[u]],dfn[u],1,id);
u = fa[top[u]];
}
if(dep[u] > dep[v]) swap(u,v);
update(1,1,n,dfn[u]+1,dfn[v],1,id);
}
inline void path_del(int u,int v,ull id)
{
while(top[u] != top[v])
{
if(dep[top[u]] < dep[top[v]]) swap(u,v);
update(1,1,n,dfn[top[u]],dfn[u],-1,id);
u = fa[top[u]];
}
if(dep[u] > dep[v]) swap(u,v);
update(1,1,n,dfn[u] + 1,dfn[v],-1,id);
}
signed main()
{
freopen("ants.in","r",stdin);freopen("ants.out","w",stdout);
// freopen("data.in","r",stdin);freopen("data.out","w",stdout);
n = read();
for(int i = 1,u,v;i < n;i ++)
{
u = read();
v = read();
add(u,v);
add(v,u);
}
dfs1(1,0);
dfs2(1,1);
build(1,1,n);
update(1,1,n,1,1,INF,INF);
for(int i = 1;i < n;i ++)
{
q[i].u = read();
q[i].v = read();
q[i].hx = i;
mp[q[i].hx] = i;
path_add(q[i].u,q[i].v,q[i].hx);
}
build2(1,1,n);
ull pos;
for(int i = 1;i < n;i ++)
{
if(tr[1].mn != 1){puts("NO");exit(0);}
pos = query(1,1,n,tr[1].id);
if(!mp.count(pos)){puts("NO");exit(0);}
path_del(q[mp[pos]].u,q[mp[pos]].v,pos);
update(1,1,n,tr[1].id,tr[1].id,INF,INF);
}
puts("YES");
Blue_Archive;
}
与你的日常,便是奇迹

浙公网安备 33010602011771号