『CF639X』

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>h2 n > 2 且 d = = 1 n>2 且 d==1 n>2d==1,证明比较显然.
构造基础:一条长度为 h h h的链,然后如果长度不够直径,则从根节点往下补一条链.最后剩下没填进去的点补在最深的链上深度为 h − 1 h-1 h1的点下方即可.

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 ci的费用换成 v + i ( 0 ≤ i ≤ 4 ) v+i(0\leq i\leq4) v+i(0i4),方便处理.若 b > 5 ∗ c b>5*c b>5c,则将 b b b换成 5 ∗ c 5*c 5c.然后开一个堆维护懒标记,直接贪心即可.

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);
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值