題目鏈接:點我啊╭(╯^╰)╮
D 0-1-Tree
題目大意:
一棵樹,邊爲 或 ,要求經過 的邊後不能走 邊,問有多少條路?
解題思路:
將邊爲 的點放到一起, 的邊放到一起,數量初始爲
從該點出發的路徑答案就是 該點 集的數量 該點 集的數量
代碼思路:
用兩個 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
題目大意:
給一個 到 的序列
計算有多少個區間滿足:
解題思路:
因爲不重複,所以一定是峯才能滿足
那麼 去找峯,處理一下峯兩邊就行了
時間複雜度:
代碼思路:
沒啥,其實當時就想到了用峯來處理,但沒想完整。。。
核心:思維很重要啊
#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);
}