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;
}

浙公网安备 33010602011771号