Codeforces Round 975 (Div. 2)(A~F)

A(见F)

代码

// Problem: F. Max Plus Min Plus Size
// Contest: Codeforces - Codeforces Round 975 (Div. 2)
// URL: https://codeforces.com/contest/2019/problem/F
// Memory Limit: 256 MB
// Time Limit: 2000 ms
// 
// Powered by CP Editor (https://cpeditor.org)

#include <bits/stdc++.h>
using namespace std;
#define LL long long
#define pb push_back
#define x first
#define y second 
#define endl '\n'
const LL maxn = 4e05+7;
#define int long long
const LL N = 5e05+10;
const LL mod = 1e09+7;
const int inf = 0x3f3f3f3f;
const LL llinf = 5e18;
typedef pair<int,int>pl;
priority_queue<LL , vector<LL>, greater<LL> >mi;//小根堆
priority_queue<LL> ma;//大根堆
struct DSU {
   
    std::vector<int> f, siz , cnt0 , cnt1 , tag , val;
    int cnt = 0;
    int tot = 0;
    DSU() {
   }
    DSU(int n) {
   
        init(n);
    }
    void init(int n) {
   
        f.resize(n);
        cnt0.resize(n);
        cnt1.resize(n);
        tag.resize(n);
        val.resize(n);
        std::iota(f.begin(), f.end(), 0);
        siz.assign(n, 1);
    }
    int find(int x) {
   
        while (x != f[x]) {
   
            x = f[x] = f[f[x]];
        }
        return x;
    }
    bool same(int x, int y) {
   
        return find(x) == find(y);
    }
    bool merge(int x, int y) {
   
        x = find(x);
        y = find(y);
        if (x == y) {
   
            return false;
        }
        if(siz[x] & 1){
   
        	swap(cnt0[y] , cnt1[y]);
        }
        siz[x] += siz[y];
        cnt0[x] |= cnt0[y];
        cnt1[x] |= cnt1[y];
		cnt -= tag[y];
		cnt -= tag[x];
		if(cnt0[x] || cnt1[x]){
   
			if(siz[x] & 1){
   
				tag[x] = cnt1[x];
			}
			else{
   
				tag[x] = 1;
			}
		}
		cnt += tag[x];
		tot -= val[x];
		tot -= val[y];
		val[x] = (siz[x] + 1) / 2;
		tot += val[x];
        f[y] = x;
        return true;
    }
    int size(int x) {
   
        return siz[find(x)];
    }
};
void solve() 
{
   
	int n;
	cin >> n;
	int a[n + 1];
	set<int>st;
	for(int i = 1 ; i <= n ; i ++){
   
		cin >> a[i];
		st.insert(a[i]);
	}	
	map<int,int>mp;
	map<int,int>pm;
	int id = 0;
	for(auto it : st){
   
		mp[it] = ++id;
		pm[id] = it;
	}
	vector<int>e[id + 1];
	//若一个并查集的大小为奇数,且奇数上有r,那么就能取到
	//若一个并查集的大小为偶数,那么无论如何都能取到r
	//我们需要知道这个并查集是否含有r,且奇数位上是否含有r
	DSU dsu(n + 1);
	int b[n + 1];
	for(int i = 1 ; i <= n ; i ++){
   
		b[i] = mp[a[i]];
	}
	for(int i = 1 ; i <= n ; i ++){
   
		if(b[i] == id){
   
			dsu.val[i] = 1;
			dsu.cnt1[i] = 1;
			dsu.tag[i] = 1;
			dsu.tot++;
			dsu.cnt++;
		}
		e[b[i]].pb(i);
	}
	int ans = 0;
	for(int l = id; l >= 1 ; l --){
   
		for(auto it : e[l]){
   
			if(l != id){
   
				dsu.val[it] = 1;
				dsu.tot++;	
			}			
		}
		for(auto it : e[l]){
   
			if(it > 1){
   
				if(b[it - 1] >= l){
   
					dsu.merge(it - 1 , it);
				}
			}
			if(it + 1 <= n){
   
				if(b[it + 1] >= l){
   
					dsu.merge(it , it + 1);
				}
			}
		}
		ans = max(ans , dsu.tot + pm[id]  - (dsu.cnt == 0));
		//cout << dsu.cnt << " " << ans << endl;
	}
	cout << ans << endl;
}            
signed main() 
{
   
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    cout.precision(10);
    int t=1;
	cin>>t;
    while(t--)
    {
   
    	solve();
    }
    return 0;
}

B

思路

	由于数轴上任意两点都能构成区间,因此对于某个数而言,其被包含的区间数量为左侧点的个数*右侧点的个数,特别的,端点处需要额外加上左
	侧端点个数(代表了左侧端点连到该端点上的区间)。

代码

// Problem: B. All Pairs Segments
// Contest: Codeforces - Codeforces Round 975 (Div. 2)
// URL: https://codeforces.com/contest/2019/problem/B
// Memory Limit: 256 MB
// Time Limit: 1500 ms
// 
// Powered by CP Editor (https://cpeditor.org)

#include <bits/stdc++.h>
using namespace std;
#define LL long long
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值