CF639A Bear and Displayed Friends
开一个小根堆,逢插入操作,若堆中元素个数小于 K K K,则直接插入,否则与堆顶判断,若大于堆顶,则弹出堆顶后插入.顺便维护一个 b o o k book book数组标记每个元素是否在堆中,插入弹出的时候维护一下下就可以了.
const ll N=3e5+5;
priority_queue<pair<ll, ll>, vector<pair<ll, ll> >, greater<pair<ll, ll> > > q;
ll n, K, Q;
bool vis[N];
ll v[N];
int main(){
read(n); read(K); read(Q);
for (R ll i=1; i<=n; i++) read(v[i]);
ll op, id;
while (Q--){
read(op); read(id);
if (op==1){
if (q.size()<K) vis[id]=true, q.push(make_pair(v[id], id));
else if (v[id]>q.top().first) vis[q.top().second]=false, q.pop(), q.push(make_pair(v[id], id)), vis[id]=true;
}else if (op==2){
if (vis[id]) puts("YES");
else puts("NO");
}
}
}
CF639B Bear and Forgotten Tree 3
比较简单的构造题.无解条件:
d
<
h
d<h
d<h或
d
>
h
∗
2
d>h*2
d>h∗2或
n
>
2
且
d
=
=
1
n>2 且 d==1
n>2且d==1,证明比较显然.
构造基础:一条长度为
h
h
h的链,然后如果长度不够直径,则从根节点往下补一条链.最后剩下没填进去的点补在最深的链上深度为
h
−
1
h-1
h−1的点下方即可.
const ll N=1e5+5;
ll n, h, d;
ll cnt;
int main(){
read(n); read(d); read(h);
if (d<h || d>h*2 || (d==1 && n>2)) return writeln(-1), 0;
for (R ll i=2; i<=h+1; i++) writesp(i-1), writeln(i);
cnt=h+1;
if (d>h){
++cnt;
writesp(1); writeln(cnt);
for (R ll i=h+3; i<=d+1; i++) ++cnt, writesp(cnt-1), writeln(cnt);
}
while (++cnt<=n) writesp(h), writeln(cnt);
}
CF639C Bear and Polynomials
由于要求
Q
(
2
)
=
0
Q(2)=0
Q(2)=0,所以我们先考虑把
P
(
2
)
P(2)
P(2)结果转化成二进制形式,然后判断每一位需要改动多少.显然只能从低位一往下改,边改边统计边算即可.
const ll N=2e5+5;
ll n, K;
ll a[N], b[N];
ll cnt, res;
int main(){
read(n); read(K);
for (R ll i=0; i<=n; i++) read(a[i]);
b[0]=a[0];
for (R ll i=1; i<=n; i++){
b[i]=b[i-1]/2+a[i];
b[i-1]%=2;
}
ll fir=0;
for (R ll i=0; i<=n; i++)
if (b[i]){
fir=i; break;
}
for (R ll i=n; i>=fir; i--){
res*=2;
res+=b[i];
if (abs(res)>2*K) return puts("0"), 0;
}
if (fir==n && a[n]==res) --cnt;
for (R ll i=fir; ~i; i--){
if (abs(a[i]-res)<=K) ++cnt;
res*=2;
if (abs(res)>2*K) break;
}
writeln(cnt);
}
CF639D Bear and Contribution
给你
n
n
n个数,把一个数加
1
1
1费用为
c
c
c,加
5
5
5费用为
b
b
b.求至少有
k
k
k个数相同的最小费用.
先分层,将每个数用 c ∗ i c*i c∗i的费用换成 v + i ( 0 ≤ i ≤ 4 ) v+i(0\leq i\leq4) v+i(0≤i≤4),方便处理.若 b > 5 ∗ c b>5*c b>5∗c,则将 b b b换成 5 ∗ c 5*c 5∗c.然后开一个堆维护懒标记,直接贪心即可.
const ll N=2e5+5;
ll n;
ll K, b, c;
vector<pair<ll, ll> > vec[5];
ll res=0x3f3f3f3f3f3f3f3f;
inline void work(ll x){
if (!vec[x].size()) return;
priority_queue<ll> q;
ll lazy_tag=0, sum=0;
q.push(vec[x][0].second);
sum+=vec[x][0].second;
for (R ll i=1; i<K; i++){
lazy_tag+=(vec[x][i].first-vec[x][i-1].first)/5*b;
sum+=(vec[x][i].second-lazy_tag);
q.push(vec[x][i].second-lazy_tag);
}
for (R ll i=K; i<n; i++){
chkmin(res, sum+K*lazy_tag);
lazy_tag+=(vec[x][i].first-vec[x][i-1].first)/5*b;
if (vec[x][i].second-lazy_tag<q.top()){
sum-=q.top(); q.pop(); q.push(vec[x][i].second-lazy_tag); sum+=vec[x][i].second-lazy_tag;
}
}
chkmin(res, sum+K*lazy_tag);
}
int main(){
read(n); read(K); read(b); read(c);
if (b>c*5) b=c*5;
for (R ll i=1, v; i<=n; i++){
read(v);
for (R ll j=0; j<5; j++)
vec[((v+j)%5+5)%5].push_back(make_pair(v+j, j*c));
}
for (R ll i=0; i<5; i++) sort(vec[i].begin(), vec[i].end());
for (R ll i=0; i<5; i++) work(i);
writeln(res);
}