hdu 4358 Boring counting(dfs序+莫队算法)
来源:互联网 发布:node v6.9.4 x64.msi 编辑:程序博客网 时间:2024/05/17 04:16
题意:给出一棵树,每个结点有一个权值,有q个查询,查询以u的子树中出现的相同权值的次数为k的数的个数。
思路:首先利用dfs可以把某个结点的子树转化成一个线性区间,然后就可以开心的用莫队搞啦~写完看了看网上的做法,发现大部分都是用线段树或树状数组过的,方法也比较巧妙……不过还是莫队比较好写啊,某些情况下莫队真是神器,时间也不太糟糕800ms+
代码:
#pragma comment(linker, "/STACK:102400000,102400000")#include<iostream>#include<cstdio>#include<cstring>#include<string>#include<algorithm>#include<map>#include<queue>#include<stack>#include<cmath>#include<vector>#define inf 0x3f3f3f3f#define Inf 0x3FFFFFFFFFFFFFFFLL#define eps 1e-9#define pi acos(-1.0)using namespace std;typedef long long ll;const int maxn=100000+10;const int size=255;struct Edge{ int v,next; Edge(){} Edge(int v,int next):v(v),next(next){}}edges[maxn];struct Query{ int L,R,id; Query(){} Query(int L,int R,int id):L(L),R(R),id(id){} bool operator <(const Query & a) const { if(L/size!=a.L/size) return L<a.L; return R<a.R; }}querys[maxn];int val[maxn],num[maxn],cnt[maxn],Lv[maxn],Rv[maxn];int head[maxn],ans[maxn],nEdge,dfs_clock,n,m,k,tot;map<int,int>mp;void Init(){ mp.clear(); memset(head,0xff,sizeof(head)); nEdge=-1;dfs_clock=0; memset(cnt,0,sizeof(cnt));}void AddEdges(int u,int v){ edges[++nEdge]=Edge(v,head[u]); head[u]=nEdge; edges[++nEdge]=Edge(u,head[v]); head[v]=nEdge;}void dfs(int u,int fa){ Lv[u]=++dfs_clock; val[dfs_clock]=num[u]; for(int k=head[u];k!=-1;k=edges[k].next) { int v=edges[k].v; if(v==fa) continue; dfs(v,u); } Rv[u]=dfs_clock;}inline void Add(int x){ if(cnt[val[x]]==k) tot--; if(cnt[val[x]]+1==k) tot++; cnt[val[x]]++;}inline void Dec(int x){ if(cnt[val[x]]==k) tot--; if(cnt[val[x]]-1==k) tot++; cnt[val[x]]--;}void solve(){ tot=0; int l=1,r=0; for(int i=0;i<m;++i) { while(querys[i].L<l) Add(--l); while(querys[i].R<r) Dec(r--); while(querys[i].L>l) Dec(l++); while(querys[i].R>r) Add(++r); ans[querys[i].id]=tot; }}int main(){ //freopen("in.txt","r",stdin); //freopen("out.txt","w",stdout); int t,tcase=0; scanf("%d",&t); while(t--) { if(tcase) printf("\n"); tcase++; Init(); scanf("%d%d",&n,&k); int u=0,v; for(int i=1;i<=n;++i) { scanf("%d",&v); if(mp[v]) num[i]=mp[v]; else num[i]=mp[v]=++u; } for(int i=1;i<n;++i) { scanf("%d%d",&u,&v); AddEdges(u,v); } dfs(1,-1); scanf("%d",&m); for(int i=0;i<m;++i) { scanf("%d",&u); querys[i]=Query(Lv[u],Rv[u],i); } sort(querys,querys+m); solve(); printf("Case #%d:\n",tcase); for(int i=0;i<m;++i) printf("%d\n",ans[i]); } return 0;}
0 0
- hdu 4358 Boring counting(dfs序+莫队算法)
- HDU 4358 Boring counting dfs序+莫队算法
- HDU 4358 Boring counting 莫队算法
- HDU Boring counting 4358 莫队算法
- HDU 4358 Boring counting 莫队算法
- HDU 4358 - Boring counting
- hdu 4358 Boring counting
- hdu 4358 Boring counting
- HDU 4358 Boring counting
- HDU 4358-I - Boring counting-dfs序+离线+树状数组/线段树
- HDU 4358 Boring counting(线段树)
- HDU 4358 Boring counting (树状数组)
- HDU 4358 Boring counting(树状数组)
- hdu 3518 Boring counting
- Boring counting HDU 3518
- hdu 3518 Boring counting
- hdu-3518-Boring counting
- HDU 3518 Boring counting
- 用心对待生活中的一切
- 小学生作文
- 定义progressbar
- Spring 详细配置
- Android开发使用adb时出现adb server is out of date的解决方法
- hdu 4358 Boring counting(dfs序+莫队算法)
- UIDatePicker的简单设置
- xen网络前后端交互
- NYOJ234吃土豆
- 执行路径问题
- photoshop--滤镜动作自动
- Spring MVC学习笔记(一) DispatcherServlet分析
- jQuery整理笔记五----jQuery事件
- listView与ScrollView的冲突