传送门

题意:

一棵树,询问一个子树内出现次数$\ge k$的颜色有几种,Candy?这个沙茶自带强制在线


吐槽:

本来一道可以离散的莫队我非要强制在线用分块做;上午就开始写了然后发现思路错了...;改 下午继续写....然后发现看大了数据范围卡空间了...;改 然后又发现好多bug...;再改 然后发现TLE了... ;改块的大小....可恶又卡空间了.... ;改short...可恶溢出了;改unsigned short....可恶n总共才1e5怎么练unsigned short也溢出了.....; 开O2...还不行....;然后发现之前把块的大小和数量搞反了....;继续改块的大小再加上有理有据对本题特性的vector优化.....终于A了.................

题解:

一开始想成已经知道k预处理f不用第三维了(md那还用分块干什么)

对出现次数$>S$和$\le S$的分开讨论

预处理$f[i][j][k]$为块i到块j出现次数$[k,S]$的有几种

$s[i][j]$为前i块颜色j出现了几次

询问的时候

两边不完整的块暴力枚举

$>S$的部分不超过$\frac{N}{S}$种,单独暴力枚举(注意如果两边枚举过了就不能重复枚举了)

$[k,S]$的部分直接用预处理的f

#pragma GCC optimize ("O2")
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <vector>
using namespace std;
typedef long long ll;
const int N=1e5+, M=, S=;
inline int read(){
char c=getchar();int x=,f=;
while(c<''||c>''){if(c=='-')f=-;c=getchar();}
while(c>=''&&c<=''){x=x*+c-'';c=getchar();}
return x*f;
} int n,Q,col,a[N],u,v,k;
int cou[N], big[N], tot, mark[N];bool biiig[N];
struct edge{int v,ne;}e[N<<];
int cnt,h[N];
inline void ins(int u,int v){
e[++cnt]=(edge){v,h[u]}; h[u]=cnt;
e[++cnt]=(edge){u,h[v]}; h[v]=cnt;
}
int dfc,L[N],R[N];
int t[N];
void dfs(int u,int fa){
L[u]=++dfc; a[dfc]=t[u];
for(int i=h[u];i;i=e[i].ne)
if(e[i].v!=fa) dfs(e[i].v, u);
R[u]=dfc;
} int block,m,pos[N];
struct _blo{int l,r;}b[M];
void ini(){
//block=sqrt(n);
block=;
m=(n-)/block+;
for(int i=;i<=n;i++) pos[i]=(i-)/block+;
for(int i=;i<=m;i++) b[i].l=(i-)*block+, b[i].r=i*block;
b[m].r=n;
} struct Block{
int f[M][M][S], c[N], s[M][N]; void Set0(int x){
for(int i=;i<=col;i++) s[x][i]=s[x-][i];
for(int i=b[x].l; i<=b[x].r; i++) s[x][a[i]]++;
} void Set1(int x){
for(int t=x;t<=m;t++){
for(int i=b[t].l; i<=b[t].r; i++) if(!biiig[ a[i] ]) c[a[i]]++;
for(int i=b[t].l; i<=b[t].r; i++) if(!biiig[ a[i] ] && c[a[i]]>){
int _=s[t-][a[i]] - s[x-][a[i]];
f[x][t][ _+c[a[i]] ]++;
f[x][t][ _ ]--;
c[a[i]]=;
}
for(int i=block; i>=; i--) f[x][t][i]+=f[x][t][i+];
for(int i=; i<=block; i++) f[x][t][i]+=f[x][t-][i];
}
} int Que(int l,int r,int k){
int pl=pos[l], pr=pos[r];
int ans=;
if(pl==pr){
for(int i=l; i<=r; i++) c[a[i]]++;
for(int i=l; i<=r; i++) if(c[a[i]]>) ans+= c[a[i]]>=k, c[a[i]]=;
}else{
for(int i=; i<=tot; i++) mark[ big[i] ]=;
vector<int> v;
int *rr=s[pr], *ll=s[pl-];
for(int i=l; i<=b[pl].r; i++){
mark[ a[i] ]=;
if(rr[a[i]] - ll[a[i]]>=k)
c[a[i]]++, v.push_back(a[i]);
}
for(int i=b[pr].l; i<=r; i++){
mark[ a[i] ]=;
if(rr[a[i]] - ll[a[i]]>=k)
c[a[i]]++, v.push_back(a[i]);
} for(int i=; i<(int)v.size(); i++) if(c[v[i]]>){
int _=s[pr-][v[i]] - s[pl][v[i]];
if(biiig[ v[i] ]) ans+= _+c[v[i]]>=k;
else ans+= (_<k && _+c[v[i]]>=k);
c[v[i]]=;
} if(k<=block) ans+=f[pl+][pr-][k];
for(int i=;i<=tot;i++) if(!mark[ big[i] ])
ans+= s[pr-][big[i]] - s[pl][big[i]] >= k;
}
return ans;
}
}B; int main(){
// freopen("in","r",stdin);
n=read(); Q=read(); ini();
for(int i=;i<=n;i++) a[i]=t[i]=read(), col=max(col, a[i]), cou[a[i]]++;
for(int i=;i<n;i++) ins(read(), read());
dfs(,); for(int i=;i<=col;i++) if(cou[i]>block) big[++tot]=i, biiig[i]=;
for(int i=;i<=m;i++) B.Set0(i);
for(int i=;i<=m;i++) B.Set1(i); while(Q--){
u=read(); k=read();
printf("%d\n", B.Que(L[u], R[u], k) );
}
}

CF 375D. Tree and Queries加强版!!!【dfs序分块 大小分类讨论】的更多相关文章

  1. Codeforces 375D Tree and Queries(DFS序+莫队+树状数组)

    题目链接  Tree and Queries 题目大意  给出一棵树和每个节点的颜色.每次询问$vj, kj$ 你需要回答在以$vj$为根的子树中满足条件的的颜色数目, 条件:具有该颜色的节点数量至少 ...

  2. CF 375D. Tree and Queries【莫队 | dsu on tree】

    题意: 一棵树,询问一个子树内出现次数$≥k$的颜色有几种 强制在线见上一道 用莫队不知道比分块高到哪里去了,超好写不用调7倍速度!!! 可以用分块维护出现次数这个权值,实现$O(1)-O(\sqrt ...

  3. CodeForces 375D Tree and Queries 莫队||DFS序

    Tree and Queries 题意:有一颗以1号节点为根的树,每一个节点有一个自己的颜色,求出节点v的子数上颜色出现次数>=k的颜色种类. 题解:使用莫队处理这个问题,将树转变成DFS序区间 ...

  4. CodeForces - 375D Tree and Queries (莫队+dfs序+树状数组)

    You have a rooted tree consisting of n vertices. Each vertex of the tree has some color. We will ass ...

  5. Codeforces 375D - Tree and Queries(dfs序+莫队)

    题目链接:http://codeforces.com/contest/351/problem/D 题目大意:n个数,col[i]对应第i个数的颜色,并给你他们之间的树形关系(以1为根),有m次询问,每 ...

  6. 【BZOJ1803】Spoj1487 Query on a tree III 主席树+DFS序

    [BZOJ1803]Spoj1487 Query on a tree III Description You are given a node-labeled rooted tree with n n ...

  7. SPOJ Query on a tree III (树剖(dfs序)+主席树 || Splay等平衡树)(询问点)

    You are given a node-labeled rooted tree with n nodes. Define the query (x, k): Find the node whose ...

  8. POJ 3321 Apple Tree (树状数组+dfs序)

    题目链接:http://poj.org/problem?id=3321 给你n个点,n-1条边,1为根节点.给你m条操作,C操作是将x点变反(1变0,0变1),Q操作是询问x节点以及它子树的值之和.初 ...

  9. SP1487 PT07J - Query on a tree III 主席树+dfs序

    Code: #include<iostream> #include<cstdio> #include<algorithm> #include<string&g ...

随机推荐

  1. PHPStorm+PHPStudy配置XDebug

    img { max-width: 100% } 上一节里面从PHPStudy+PHPStorm的配置,到最后发布,PHPStorm只是承担了编辑器和发布站点的任务,但是还没有办法像Visual Stu ...

  2. [学习OpenCV攻略][003[初试牛刀——显示图片]

    cvLoadImage(路径) 加载指定路径的图片到内存 cvNamedWindow("窗口名称", 属性) 创建窗口,窗口名称用来被其他函数引用,属性:0表示窗口大小不变,CV_ ...

  3. js判断是否为ie浏览器

    之前在开发时遇到浏览器的兼容性问题,涉及到对ie浏览器的判断.现在此做个笔记. 这里我以函数的形式来判断,在用的时候直接调用即可. var isIE = !!window.ActiveXObject ...

  4. setTimeout()方法,你真的懂吗?

    今天在群里看到了一道经典的javascript题型,之前也遇到过,可是再次遇到时,还是做错,还是不理解,因此这里来做个笔记吧! 不说了,直接上代码吧 for(var i=1; i<=9; i++ ...

  5. 话说TP框架里的Vendor这目录是干什么用的啊?类库扩展thinkphp3.1版本

    类库扩展包括基类库扩展.应用类库扩展和第三方类库扩展,所有扩展类库不会自动加载,需要手动加载或者定义别名和配置自动加载(详细可以参考4.2.3类库导入和4.2.5自动加载). 1 基类库扩展 目前支持 ...

  6. jquery 图片自动无缝滚动

    <!DOCTYPE html><html><head> <meta charset="utf-8"> <meta http-e ...

  7. 苹果新贵 Swift 之前世今生

    摘要 : 做为一个70后程序员,克里斯先后发明了 LLVM.Clang 和 Swift,请问你做了什么?   上 周出差劳顿,这篇文章几次动笔都未完成,常常躺倒床上就昏睡过去.南方的天气闷热潮湿,让我 ...

  8. RPC架构简单理解

    RPC(Remote Promote Call) 一种进程间通信方式.允许像调用本地服务一样调用远程服务. RPC框架的主要目标就是让远程服务调用更简单.透明.RPC框架负责屏蔽底层的传输方式(TCP ...

  9. 一次__libc_message的排查

     信号是6,abort调用的.总体而言,当你malloc的指针为A,但是你free的指针不是A,则容易出这个错,当然假设你free的刚好是别人malloc的,则还是正常. 还有一种是你free的地址在 ...

  10. IOS 设置文件是否使用ARC

    全项目设置:Building Settings修改Objective-C Automatic Reference Counting设置是否使用 单文件设置:Build Phases-Compile S ...