Educational Codeforces Round 172 (Rated for Div. 2)(C-D)

题目链接:Dashboard - Educational Codeforces Round 172 (Rated for Div. 2) - Codeforces

C. Competitive Fishing

tag:后缀和 + 思维

Description:有一个序列含n个数(每个数是01),将其分为m个区间,从前往后每个区间中第i个区间的权值为(i1),求序列权值和大于等于k的最小区间划分数,如果不能输出1

Solution:在第i个数前面划分一次的贡献为其后缀和,因此我们贪心的取后缀和即可,注意第一个数前面不能划分。

%%
1
4 4
0011
3
%%
void solve(){
int n, k;
string ss;
cin >> n >> k >> ss;
ss = '&' + ss;
vector<int> a(n + 1), s(n + 2);
for (int i = 1; i <= n; i ++){
if (ss[i] == '1')
a[i] = 1;
else
a[i] = -1;
}
priority_queue<int> qu;
for (int i = n; i > 1; i --){ // 后缀和
s[i] = s[i + 1] + a[i];
qu.push(s[i]);
}
int ans = 0, sum = 0;
while (qu.size()){
sum += qu.top();
qu.pop();
ans ++;
if (sum >= k){
cout << ans + 1 << endl;
return;
}
}
cout << -1 << endl;
}

D. Recommendations

tag:思维

Description:给定n个区间[l,r],输入所有包含该区间的公共区间减去该区间的长度。1 <= n <= 2e15, 1 <= l <= r <= 1e9

Solution:区间问题考虑先排序再处理。用两个数组R[i],L[i],存储第i个区间对应的右边界和左边界。考虑如何求右边界。

  • 显然需要按左端点从小到大排序,因为需要左边包含当前区间,同时右端点从大到小排序,让能包含的区间先出现。
  • 左边界同理。
  • 如果有两个区间相同特判为0。(用map记录)

trick:区间问题考虑先排序再处理用set自带的st.lower_bound()比lower_bound函数快,但是前者返回的是迭代器。

struct node{
int l, r, id;
};
bool cmp1(node a, node b){ // 左端点从小到大排序,右端点大在前,计算Ri
if (a.l == b.l)
return a.r > b.r;
else
return a.l < b.l;
}
bool cmp2(node a, node b){
if (a.r == b.r)
return a.l < b.l;
else
return a.r > b.r;
}
void solve(){
int n;
cin >> n;
vector<node> a(n);
vector<node> id(n);
map<pii, int> mp;
for (int i = 0; i < n; i ++){
cin >> a[i].l >> a[i].r;
a[i].id = i;
id[i] = a[i];
mp[{a[i].l, a[i].r}] ++;
}
vector<int> L(n), R(n);
sort(a.begin(), a.end(), cmp1);
set<int> st;
for (int i = 0; i < n; i ++){
if (st.size() == 0){
R[a[i].id] = a[i].r;
}
else{
if (st.lower_bound(a[i].r) == st.end()){
R[a[i].id] = a[i].r;
}
else{
int xr = *(st.lower_bound(a[i].r));
R[a[i].id] = xr;
}
}
st.insert(a[i].r);
}
st.clear();
sort(a.begin(), a.end(), cmp2);
for (int i = 0; i < n; i ++){
if (st.size() == 0){
L[a[i].id] = a[i].l;
}
else{
if (st.lower_bound(-a[i].l) == st.end()){
L[a[i].id] = a[i].l;
}
else{
int xr = *(st.lower_bound(-a[i].l));
L[a[i].id] = -xr;
}
}
st.insert(-a[i].l);
}
for (int i = 0; i < n; i ++){
if (mp[{id[i].l, id[i].r}] > 1){
cout << 0 << endl;
}
else
cout << (R[i] - id[i].r) + (id[i].l - L[i]) << endl;
}
}
posted @   Sakura17  阅读(5)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 全网最简单!3分钟用满血DeepSeek R1开发一款AI智能客服,零代码轻松接入微信、公众号、小程
· .NET 10 首个预览版发布,跨平台开发与性能全面提升
· 《HelloGitHub》第 107 期
· 全程使用 AI 从 0 到 1 写了个小工具
· 从文本到图像:SSE 如何助力 AI 内容实时呈现?(Typescript篇)
点击右上角即可分享
微信分享提示