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\)个数(每个数是\(0\)\(-1\)),将其分为\(m\)个区间,从前往后每个区间中第\(i\)个区间的权值为\((i - 1)\),求序列权值和大于等于\(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 @ 2024-12-27 18:27  Sakura17  阅读(53)  评论(0)    收藏  举报