CodeForces 375D Tree and Queries
生活随笔
收集整理的這篇文章主要介紹了
CodeForces 375D Tree and Queries
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
傳送門:https://codeforces.com/problemset/problem/375/D
題意:
給你一顆有根樹,樹上每個節點都有其對應的顏色,有m次詢問,每次問你以點v為父節點的子樹內滿足某種顏色的數量大于k的顏色一共有多少種
題解:
冷靜分析,胡亂分析,詢問次數這么多,但是并沒有修改操作,倘若把詢問離線下來就好了
可是詢問問的是每個點的樹
這個時候我們的dfs序就可以派上用場了
dfs序:"所謂DFS序, 就是DFS整棵樹依次訪問到的結點組成的序列"
"DFS序有一個很強的性質: 一顆子樹的所有節點在DFS序內是連續的一段, 利用這個性質我們可以解決很多問題"
通過對樹進行一次dfs序操作,我們可以得到每個點他的子樹所在的一段區間,這樣我們就可以得到每個詢問在dfs序下詢問的區間了,那么我們怎么統計區間內顏色數量大于k的種類數量呢?
由于我們得到了離線下來的詢問區間,用莫隊算法可以在O(nsqrt(n))的時間內得到所有詢問的答案
由于每次詢問是查詢區間內顏色種類的數量之和,我們需要用一個區間求和,單點修改的數據結構來維護莫隊時統計答案和修改操作,因此我們可以用樹狀數組或者線段樹來維護
代碼:
/*** ┏┓ ┏┓* ┏┛┗━━━━━━━┛┗━━━┓* ┃ ┃ * ┃ ━ ┃* ┃ > < ┃* ┃ ┃* ┃... ⌒ ... ┃* ┃ ┃* ┗━┓ ┏━┛* ┃ ┃ Code is far away from bug with the animal protecting * ┃ ┃ 神獸保佑,代碼無bug* ┃ ┃ * ┃ ┃ * ┃ ┃* ┃ ┃ * ┃ ┗━━━┓* ┃ ┣┓* ┃ ┏┛* ┗┓┓┏━┳┓┏┛* ┃┫┫ ┃┫┫* ┗┻┛ ┗┻┛*/
// warm heart, wagging tail,and a smile just for you!
//
// _ooOoo_
// o8888888o
// 88" . "88
// (| -_- |)
// O\ = /O
// ____/`---'\____
// .' \| |// `.
// / \||| : |||// \
// / _||||| -:- |||||- \
// | | \\ - /// | |
// | \_| ''\---/'' | |
// \ .-\__ `-` ___/-. /
// ___`. .' /--.--\ `. . __
// ."" '< `.___\_<|>_/___.' >'"".
// | | : `- \`.;`\ _ /`;.`/ - ` : | |
// \ \ `-. \_ __\ /__ _/ .-` / /
// ======`-.____`-.___\_____/___.-`____.-'======
// `=---='
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
// 佛祖保佑 永無BUG
#include <set>
#include <map>
#include <deque>
#include <queue>
#include <stack>
#include <cmath>
#include <ctime>
#include <bitset>
#include <cstdio>
#include <string>
#include <vector>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;typedef long long LL;
typedef pair<LL, LL> pLL;
typedef pair<LL, int> pLi;
typedef pair<int, LL> pil;;
typedef pair<int, int> pii;
typedef unsigned long long uLL;
#define ls rt<<1
#define rs rt<<1|1
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
#define bug printf("*********\n")
#define FIN freopen("input.txt","r",stdin);
#define FON freopen("output.txt","w+",stdout);
#define IO ios::sync_with_stdio(false),cin.tie(0)
#define debug1(x) cout<<"["<<#x<<" "<<(x)<<"]\n"
#define debug2(x,y) cout<<"["<<#x<<" "<<(x)<<" "<<#y<<" "<<(y)<<"]\n"
#define debug3(x,y,z) cout<<"["<<#x<<" "<<(x)<<" "<<#y<<" "<<(y)<<" "<<#z<<" "<<z<<"]\n"const double eps = 1e-8;
const int mod = 1e9 + 7;
const int maxn = 3e5 + 5;
const int INF = 0x3f3f3f3f;
const LL INFLL = 0x3f3f3f3f3f3f3f3f;
struct EDGE {int v, nxt;
} edge[maxn * 2];
int head[maxn];
int tot;
void add_edge(int u, int v) {edge[tot].v = v;edge[tot].nxt = head[u];head[u] = tot++;
}
int n, m;
int col[maxn];
int dfn[maxn], st[maxn], ed[maxn], cnt;
int vis[maxn];
int num[maxn];
int bit[maxn];
int ans[maxn];
void dfs(int u, int fa, int depth) {st[u] = ++cnt;num[cnt] = col[u];for(int i = head[u]; i != -1; i = edge[i].nxt) {int v = edge[i].v;if(v != fa) {dfs(v, u, depth + 1);}}ed[u] = cnt;
}
vector<int> vec[maxn];
int v[maxn];
int k[maxn];
struct node {int l, r, id, k;
} q[maxn];
int pos[maxn];
bool cmp(node a, node b) {if(pos[a.l] == pos[b.l]) return a.r < b.r;return pos[a.l] < pos[b.l];
}
int lowbit(int x) {return x & -x;
}
void update(int pos, int x) {if(pos <= 0) return;while(pos < maxn) {bit[pos] += x;pos += lowbit(pos);}
}
int query(int pos) {int ans = 0;while(pos) {ans += bit[pos];pos -= lowbit(pos);}return ans;
}
void add(int x) {update(vis[num[x]], -1);vis[num[x]]++;update(vis[num[x]], 1);
}
void del(int x) {update(vis[num[x]], -1);vis[num[x]]--;update(vis[num[x]], 1);
}
int main() {
#ifndef ONLINE_JUDGEFIN
#endifscanf("%d%d", &n, &m);for(int i = 1; i <= n; i++) {scanf("%d", &col[i]);}memset(head, -1, sizeof(head));tot = cnt = 0;for(int i = 1, u, v; i <= n - 1; i++) {scanf("%d%d", &u, &v);add_edge(u, v);add_edge(v, u);}dfs(1, 0, 1);int sz = sqrt(cnt);for(int i = 1; i <= cnt; i++) {pos[i] = i / sz;}for(int i = 1; i <= m; i++) {scanf("%d%d", &v[i], &k[i]);q[i].l = st[v[i]];q[i].r = ed[v[i]];q[i].id = i;q[i].k = k[i];}sort(q + 1, q + m + 1, cmp);int L = 1, R = 0;for(int i = 1; i <= m; i++) {while(L < q[i].l) {L++;del(L - 1);}while(L > q[i].l) {add(L - 1);L--;}while(R < q[i].r) {R++;add(R);}while(R > q[i].r) {del(R);R--;}ans[q[i].id] = query(maxn - 1) - query(q[i].k - 1);}for(int i = 1; i <= m; i++) {printf("%d\n", ans[i]);}return 0;
}
轉載于:https://www.cnblogs.com/buerdepepeqi/p/10897505.html
總結
以上是生活随笔為你收集整理的CodeForces 375D Tree and Queries的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: DS博客作业04--树大作业
- 下一篇: Python元组字典