Codeforces Round 1064题解

前言

当时非常不想打但还是打了,非常没有耐心,导致B题题目太长不想看,C题题目看错导致20分钟没了,然后就不想做了,于是现在补题,准备今晚的div3.如果我有耐心的话。

题目

A. Same Difference

只能前一个数等于后一个数,操作最后所有数都只会等于 \(a_n\),直接统计不等于 \(a_n\) 的个数就行。

B. Tab Closing

还是得多读题,多看几遍我现在就会了,标签长度只会是 \(\min{b,\frac{a}{m}}\),可以想到剩余的数只会越来越少,那么 \(\frac{a}{m}\) 会不断增大,那对于 \(b\) 本身就最小的情况下,长度不会边,对于 \(\frac{a}{m}\) 为最小的情况下,看他是否会超过 \(b\) 了,如果超过就动 \(2\) 次,否则就 \(1\) 次。

ps:这个动 \(1\) 次是动到末尾那个。

C. Cyclic Merging

偷看到了双向链表,所以想到每次肯定合并相邻最接近的数,而且要保证每次要进行合并的数要从小到大,要用优先队列来维护。

#include<bits/stdc++.h>
#define ll long long
#define int ll
using namespace std;
const int N=1e6+10;
mt19937 rnd(251);

int n;
int a[N];
int l[N],r[N];
int vis[N];

struct ss{ 
	int val,id;
	bool operator()(const ss& g,const ss& h)const{
		return g.val>h.val;
	}
};

priority_queue<ss,vector<ss>,ss> q; 

void solve(){
	int m;
	cin>>n;
	m=n;
	for(int i=1;i<=n;i++){
		cin>>a[i];
		vis[i]=0;
		l[i]=i-1;
		r[i]=i+1;
		q.push({a[i],i});
	}
	l[1]=n;
	r[n]=1;
	int ans=0;
	
	while(n>1){
		ss g=q.top();
		int i=g.id;
		q.pop();
		if(vis[i]){
			continue;
		}
		vis[i]=1;
		if(a[l[i]]<=a[r[i]]){
			ans+=max(a[i],a[l[i]]);
			a[l[i]]=max(a[i],a[l[i]]);
			q.push({a[l[i]],l[i]});
			r[l[i]]=r[i];
			l[r[i]]=l[i];
		}
		else{
			ans+=max(a[i],a[r[i]]);
			a[r[i]]=max(a[i],a[r[i]]);
			q.push({a[r[i]],r[i]});
			r[l[i]]=r[i];
			l[r[i]]=l[i];
		}
		n--;
	}
	cout<<ans<<'\n';
	while(!q.empty()){
		q.pop();
	}
}

signed main(){
    ios::sync_with_stdio(0);
    cin.tie(nullptr);
    int t=1;
	cin>>t;
	while(t--){
		solve();
	} 
    return 0;
}
posted @ 2025-11-18 15:33  sad_lin  阅读(9)  评论(0)    收藏  举报