Educational CF Round 64 (Div. 2)___D DSU E 貪心

題目鏈接:點我啊╭(╯^╰)╮

D 0-1-Tree

題目大意:

     一棵樹,邊爲 0011,要求經過 11 的邊後不能走 00 邊,問有多少條路?

解題思路:

    將邊爲 00 的點放到一起,11 的邊放到一起,數量初始爲 11
    從該點出發的路徑答案就是 該點 00 集的數量 * 該點 11 集的數量 1- 1

代碼思路:

    用兩個 DSU 就行了

核心:DSU運用

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair <int,int> pii;
const ll mod = 1e9 + 7;
const int maxn = 3e5 + 10;
int n, ans;
int f0[maxn], f1[maxn];
int si0[maxn], si1[maxn];

int find0(int v) {
	return f0[v] == v ? v : f0[v] = find0(f0[v]);
}
int find1(int v) {
	return f1[v] == v ? v : f1[v] = find1(f1[v]);
}

int main(){
	scanf("%d", &n);
	for(int i=1; i<=n; i++){
		f0[i] = f1[i] = i;
		si0[i] = si1[i] = 1;
	}
	int u, v, c;
	for(int i=1; i<n; i++){
		scanf("%d%d%d", &u, &v, &c);
		if(c){
			u = find1(u), v =find1(v);
			f1[u] = v;
			si1[v] += si1[u];
		}
		else {
			u = find0(u), v =find0(v);
			f0[u] = v;
			si0[v] += si0[u];
		}
	}
	
	ll ans = 0;
	for(int i=1; i<=n; i++)
		ans += 1ll * si0[find0(i)] * si1[find1(i)] - 1;
	printf("%lld\n", ans);
}

E Special Segments of Permutation

題目大意:

     給一個 11nn 的序列 pp
     計算有多少個區間滿足:
     pl+pr=maxi=lrpip_l + p_r = \max \limits_{i = l}^{r} p_i

解題思路:

    因爲不重複,所以一定是峯才能滿足
    那麼 OnOn 去找峯,處理一下峯兩邊就行了
    時間複雜度:OnOn

代碼思路:

    沒啥,其實當時就想到了用峯來處理,但沒想完整。。。

核心:思維很重要啊

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair <int,int> pii;
const ll mod = 1e9 + 7;
const int maxn = 3e5 + 10;
int n, ans, p[maxn], to[maxn];

int main() {
	scanf("%d", &n);
	for(int i=0; i<n; i++) scanf("%d", p+i);
	for(int i=1; i<n-1; i++) {
		if(p[i]>p[i-1] && p[i]>p[i+1]) {
			int cur = p[i];
			for(int j=i-1; j>=0 && p[j]<cur; j--) to[p[j]] = cur;
			for(int j=i+1; j<n && p[j]<cur; j++)
				if(to[cur-p[j]]==cur)
					ans++;
		}
	}

	printf("%d\n", ans);
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章