HDU4358【离散化+DFS序+莫队算法】
来源:互联网 发布:阿里云yum安装mysql 编辑:程序博客网 时间:2024/05/07 06:11
思路:
这个DFS序还是蛮有意思的~然后就可以把以u为根的树的状态直接转化到区间(一维数组)上,而且数组是不大的。
然后就变成了区间处理,套一下莫队就好了。
Code:
#include<bits/stdc++.h>using namespace std;typedef long long LL;#define mem(a, b) memset(a, b, sizeof(a))const int Maxn = 1e5 + 10;struct Edge{int v, nex;}edge[Maxn<<1];int head[Maxn], tol;void init(){tol = 0,mem(head, -1);}void addedge(int u, int v){ edge[tol] = (Edge){v, head[u]}, head[u] = tol++; edge[tol] = (Edge){u, head[v]}, head[v] = tol++;}int w[Maxn], _time, val[Maxn], n, k, q, a[Maxn];int Left[Maxn], Right[Maxn];vector<int>xs;struct asd{ int id; int Left, Right;}node[Maxn];int res[Maxn], ans, sum[Maxn];int pos[Maxn];bool cmp(asd x,asd y){ if(pos[x.Left] == pos[y.Left]) return x.Right<y.Right; return pos[x.Left]<pos[y.Left];}void DFS(int u, int fa){ int v; Left[u] = ++_time, w[_time] = a[u]; for(int i=head[u]; ~i;i = edge[i].nex){ v = edge[i].v; if(v == fa) continue; DFS(v, u); } Right[u] = _time;}void ADD(int ww){ if(sum[ww] == k) ans--; sum[ww]++; if(sum[ww] == k) ans++;}void DEL(int ww){ if(sum[ww] == k) ans--; sum[ww]--; if(sum[ww] == k) ans++;}void solve(){ ans=0; mem(sum, 0); sort(node+1, node+1+q, cmp); for(int i=node[1].Left;i<=node[1].Right;i++){ ADD(w[i]); } res[node[1].id]=ans; int L=node[1].Left,R=node[1].Right; for(int i=2; i<=q; i++){ while(R<node[i].Right){ R++; ADD(w[R]); } while(R>node[i].Right){ DEL(w[R]); R--; } while(L<node[i].Left){ DEL(w[L]); L++; } while(L>node[i].Left){ L--; ADD(w[L]); } res[node[i].id]=ans; } for(int i=1;i<=q;i++) printf("%d\n", res[i]);}int main(){ int T, u, v, L, R; scanf("%d", &T); for(int cas = 1; cas <= T; cas++){ scanf("%d%d",&n, &k); xs.clear(); int block=(int)sqrt(n); for(int i=1;i<=n;i++){ scanf("%d", &a[i]); xs.push_back(a[i]); pos[i]=(i-1)/block+1; } sort(xs.begin(), xs.end()); xs.erase(unique(xs.begin(), xs.end()), xs.end()); for(int i=1;i<=n;++i) a[i] = lower_bound(xs.begin(), xs.end(), a[i]) - xs.begin() + 1; init(); for(int i=1;i<n;i++){ scanf("%d%d", &u, &v); addedge(u, v); } _time = 0; DFS(1, -1); scanf("%d", &q); for(int i=1;i<=q;i++){ scanf("%d", &u); node[i].id = i; node[i].Left = Left[u], node[i].Right = Right[u]; } printf("Case #%d:\n", cas); solve(); if(cas != T) puts(""); } return 0;}
阅读全文
0 0
- HDU4358【离散化+DFS序+莫队算法】
- Coconuts----DFS+离散化
- nbut1457 Sona 【莫队算法+离散化】
- NBUT 1457 (莫队算法 离散化)
- HDU 5925 离散化+dfs
- hdu 5877 离散化+树状数组+dfs序
- 莫队 + dfs序 + 离散化处理 HDU 4358
- HDU 5877 Weak Pair dfs序 + 树状数组 + 离散化
- NBUT 1457 Sona(莫队算法+离散化)
- BZOJ3289【莫队算法+树状数组+离散化】
- 算法中的离散化
- hdu4605 树状数组+离散化+dfs
- FZU 2227 邮票 (DFS+ 离散化 水题)
- CodeForcse 29C (DFS+离散化)
- hdu 5877 线段树+离散化+DFS
- hdu5877 dfs+线段树离散化
- hdu 5877 dfs+离散化+树状数组
- HDU5877 线段树,离散化,Dfs
- HDU 1950(LIS)
- syntax error: non-declaration statement outside function body
- 关于Java中的 i = i ++ 的问题
- 聊天室
- [编程题] 头条校招
- HDU4358【离散化+DFS序+莫队算法】
- AI开发实战3-定制自己的Screen
- leetcode[Longest Harmonious Subsequence]
- 面向对象编程思想-观察者模式
- linux TCP 参数设置
- X^2 Mod P
- 阶乘-递归-java
- Css 学习笔记--样式引入方式及按权重判断优先级
- 《JS高级程序设计》第6章读书笔记:创建对象(二)原型模式和组合模式