传送门

题意:

一棵树,询问一个子树内出现次数$\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. codeforce 375_2_b_c

    codeforce 375_2 标签: 水题 好久没有打代码,竟然一场比赛两次卡在边界条件上....跪 b.题意很简单...纯模拟就可以了,开始忘记了当字符串结束的时候也要更新两个值,所以就错了 #i ...

  2. HDU--1060

    Leftmost Digit Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) T ...

  3. Ubuntu搭建Gitlab服务器

    想到Gitlab就必定会想到SVN,因为两者都是代码管理系统,作为开发人员来说,用习惯了SVN的图形化界面和SVN代码更新和提交的方式, 可能就会觉得使用git会比较麻烦,其实不然git使用起来非常方 ...

  4. Logstash+Kibana部署配置

    Logstash是一个接收,处理,转发日志的工具.支持系统日志,webserver日志,错误日志,应用日志,总之包括所有可以抛出来的日志类型. 典型的使用场景下(ELK): 用Elasticsearc ...

  5. [国嵌攻略][156][I2C自编设备驱动设计]

    AT24C08的驱动在Linux内核中已经提供,在/drivers/misc/eeprom/at24.c文件中.在对应的probe函数中有一个创建/sys/.../eeprom文件的函数,应用程序通过 ...

  6. 我的第一个python web开发框架(20)——产品发布(部署到服务器)

    首先按上一章节所讲述的,将服务器环境安装好以后,接下来就是按步骤将网站部署到服务器上了. 我们的站点是前后端分离的,所以需要部署两个站点.首先来发布前端站点. 部署前端站点 输入命令进入svn管理文件 ...

  7. JavaScript八张思维导图—基本概念

    JS基本概念 JS操作符 JS基本语句 JS数组用法 Date用法 JS字符串用法 JS编程风格 JS编程实践 不知不觉做前端已经五年多了,无论是从最初的jQuery还是现在火热的Angular,Vu ...

  8. javascript 思维导图 总结

    项目接近尾声,闲暇时间对JavaScript的总结,包含数组的一些知识(创建.访问.关联数组,数组API,以及二维数组).js的内置对象.面向对象概念和特征.以及部分ES5特性. 大纲如图: 如需可下 ...

  9. 从零开始学习前端开发 — 16、CSS3圆角与阴影

    一.css3圆角: border-radius:数值+单位; 1.设置一个值:border-radius:20px; 四个方向圆角都为20px(水平半径和垂直半径相等) 2.设置两个值 border- ...

  10. vue2.0集成百度UE编辑器,上传图片报错!!!

    我这边配置进去之后,界面加载,文本输入都没有问题,就是上传图片会有问题 这张图, 左边红色框框 就是目录结构咯, 右边红色框框 就是各种网上教程给出的第一个路径配置对吧, 下面的就是绿色 服务器接口配 ...