【DFS序】【莫队算法】【权值分块】bzoj2809 [Apio2012]dispatching
题意:在树中找到一个点i,并且找到这个点子树中的一些点组成一个集合,使得集合中的所有点的c之和不超过M,且Li*集合中元素个数和最大
首先,我们将树处理出dfs序,将子树询问转化成区间询问。
然后我们发现,对于单一节点来说,“使得集合中的所有点的c之和不超过M,且Li*集合中元素个数和最大”可以贪心地搞,即优先选择c较小的点。(<--这正是主席树/权值线段树/权值分块的工作)
但是我们需要枚举所有节点,从他们中选一个最大的。
既然有dfs序了,那么就是无修改的区间询问咯。(<--莫队的工作) 但是莫队转移的过程中,主席树/权值线段树的插入/删除无法承受。(当然主席树根本就用不着莫队,也可以解决这个问题,但这不是这篇文章要介绍的) 权值分块的插入/删除是O(1)的,查询是O(sqrt(n))的,总复杂度仍是O(n*sqrt(n))的。
编程复杂度较低,常数较小。
#include<cstdio>
#include<algorithm>
#include<cmath>
using namespace std;
typedef long long ll;
ll sumv[330],m,ans;
int num2[100001],num[100001],l[330],cnts[330],b[100001],sum=1;
struct Point{int v,p;}t[100001];
struct Ask{int l,r,p;}Q[100001];
bool operator < (const Point &a,const Point &b){return a.v<b.v;}
bool operator < (const Ask &a,const Ask &b)
{return num2[a.l]!=num2[b.l] ? num2[a.l]<num2[b.l] : a.r<b.r;}
int v[100001],first[100001],next[100001];
int n,es,p,w[100001],w2[100001],L,a[100001],ma[100001],en,lead[100001];
void AddEdge(const int &U,const int &V)
{
v[++es]=V;
next[es]=first[U];
first[U]=es;
}
void dfs(int U)
{
Q[U].l=++L; t[L].v=w[U]; t[L].p=L; lead[L]=w2[U];
for(int i=first[U];i;i=next[i]) dfs(v[i]);
Q[U].r=L; Q[U].p=U;
}
void Val_Make_Block()
{
int sz=sqrt(en); if(!sz) sz=1;
for(;sum*sz<en;++sum)
{
l[sum]=(sum-1)*sz+1; int r=sum*sz;
for(int i=l[sum];i<=r;++i) num[i]=sum;
}
l[sum]=(sum-1)*sz+1;
for(int i=l[sum];i<=en;++i) num[i]=sum;
}
void Mo_Make_Block()
{
int sum=1,sz=sqrt(n); if(!sz) sz=1;
for(;sum*sz<n;++sum)
{
int r=sum*sz;
for(int i=(sum-1)*sz+1;i<=r;++i) num2[i]=sum;
}
for(int i=(sum-1)*sz+1;i<=n;++i) num2[i]=sum;
}
void Insert(const int &x){++b[x]; ++cnts[num[x]]; sumv[num[x]]+=(ll)ma[x];}
void Delete(const int &x){--b[x]; --cnts[num[x]]; sumv[num[x]]-=(ll)ma[x];}
int Query()
{
ll tot=0; int res=0;
for(int i=1;i<=sum;++i)
{
tot+=sumv[i]; res+=cnts[i];
if(tot>m)
{
tot-=sumv[i]; res-=cnts[i];
for(int j=l[i];;++j)
{
tot+=((ll)ma[j]*(ll)b[j]);
res+=b[j];
if(tot>m) return res-(int)((tot-m)/ma[j])-((tot-m)%ma[j]!=0);
}
}
}
return res;
}
int main()
{
scanf("%d%lld",&n,&m);
for(int i=1;i<=n;++i)
{
scanf("%d%d%d",&p,&w[i],&w2[i]);
AddEdge(p,i);
}
dfs(1); sort(t+1,t+n+1);
ma[a[t[1].p]=++en]=t[1].v;
for(int i=2;i<=n;++i)
{
if(t[i].v!=t[i-1].v) ++en;
ma[a[t[i].p]=en]=t[i].v;
}
Val_Make_Block(); Mo_Make_Block();
sort(Q+1,Q+n+1);
for(int i=Q[1].l;i<=Q[1].r;++i) Insert(a[i]);
ans=max(ans,(ll)Query()*(ll)lead[Q[1].l]);
for(int i=2;i<=n;++i)
{
if(Q[i].l<Q[i-1].l) for(int j=Q[i-1].l-1;j>=Q[i].l;--j) Insert(a[j]);
else for(int j=Q[i-1].l;j<Q[i].l;++j) Delete(a[j]);
if(Q[i].r<Q[i-1].r) for(int j=Q[i-1].r;j>Q[i].r;--j) Delete(a[j]);
else for(int j=Q[i-1].r+1;j<=Q[i].r;++j) Insert(a[j]);
ans=max(ans,(ll)Query()*(ll)lead[Q[i].l]);
}
printf("%lld\n",ans);
return 0;
}
【DFS序】【莫队算法】【权值分块】bzoj2809 [Apio2012]dispatching的更多相关文章
- HDU 4358 Boring counting dfs序+莫队算法
题意:N个节点的有根树,每个节点有一个weight.有Q个查询,问在以u为根的子树中,有恰好出现了K次的weight有多少种. 这是第一次写莫队算法,之前也只是偶有耳闻. 看了别人的代码打的,还是贴上 ...
- hdu 4358 Boring counting 离散化+dfs序+莫队算法
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4358 题意:以1为根节点含有N(N <= 1e5)个结点的树,每个节点有一个权值(weight ...
- BZOJ2038: [2009国家集训队]小Z的袜子(hose) -- 莫队算法 ,,分块
2038: [2009国家集训队]小Z的袜子(hose) Time Limit: 20 Sec Memory Limit: 259 MBSubmit: 3577 Solved: 1652[Subm ...
- 莫队算法 sqrt(n)分块思想
在此说一下本渣对莫队算法思想的一些浅薄理解 莫队算法的思想就是对真个区间的分块,然后按照每块来分别进行计算,这样最终的复杂度可以达到n*sqrt(n) 小Z的袜子是一道非常经典的题目.:题目链接htt ...
- hdu 4358 Boring counting dfs序+莫队+离散化
Boring counting Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 98304/98304 K (Java/Others) ...
- CF600E Lomsat gelral (dfs序+莫队)
题面 题解 看到网上写了很多DSU和线段树合并的题解,笔者第一次做也是用的线段树合并,但在原题赛的时候却怕线段树合并调不出来,于是就用了更好想更好调的莫队. 这里笔者就说说莫队怎么做吧. 我们可以通过 ...
- Codeforces 375D - Tree and Queries(dfs序+莫队)
题目链接:http://codeforces.com/contest/351/problem/D 题目大意:n个数,col[i]对应第i个数的颜色,并给你他们之间的树形关系(以1为根),有m次询问,每 ...
- Codeforces 375D Tree and Queries(DFS序+莫队+树状数组)
题目链接 Tree and Queries 题目大意 给出一棵树和每个节点的颜色.每次询问$vj, kj$ 你需要回答在以$vj$为根的子树中满足条件的的颜色数目, 条件:具有该颜色的节点数量至少 ...
- Luogu 1494 - 小Z的袜子 - [莫队算法模板题][分块]
题目链接:https://www.luogu.org/problemnew/show/P1494 题目描述 作为一个生活散漫的人,小Z每天早上都要耗费很久从一堆五颜六色的袜子中找出一双来穿.终于有一天 ...
- 莫队或权值线段树 或主席树 p4137
题目描述 有一个长度为n的数组{a1,a2,…,an}.m次询问,每次询问一个区间内最小没有出现过的自然数. 输入格式 第一行n,m. 第二行为n个数. 从第三行开始,每行一个询问l,r. 输出格式 ...
随机推荐
- 谈一谈深度学习之semantic Segmentation
上一次发博客已经是9月份的事了....这段时间公司的事实在是多,有写博客的时间都拿去看paper了..正好春节回来写点东西,也正好对这段时间做一个总结. 首先当然还是好好说点这段时间的主要工作:语义分 ...
- Codeforces Round #348 (VK Cup 2016 Round 2, Div. 2 Edition) D
D. Little Artem and Dance time limit per test 2 seconds memory limit per test 256 megabytes input st ...
- ionic3自定义图标
http://blog.csdn.net/qq993284758/article/details/78107412
- 带依赖包的maven打包配置
转载自:http://outofmemory.cn/code-snippet/2594/carry-yilai-bao-maven-dabao-configuration 可以在maven的packa ...
- 《vue.js实战》练习---标签页组件
html: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF ...
- 有关eclipse的内存溢出问题
一:前言 最近在做的项目在启动tomcat时就报“内存溢出的错误”,其实也不是自己第一次遇到,但是每次都是在网上查询后敲进去,所以这次我觉得自己记载下来吧. 二:内容 我自己的配置大小,这里的配置位置 ...
- Spring + Mybatis - 原始dao开发整合 与 Mapper代理整合
Spring + Mybatis - 原始dao开发整合 与 Mapper代理整合 标签: mybatisSpringbeanApplicationContextMapper 2015-12-31 1 ...
- SSL_TLS
http://www.ruanyifeng.com/blog/2014/02/ssl_tls.html 配置 IBM HTTP Server 以支持 TLS 1.2 http://www-01.ibm ...
- 【BZOJ1419】 Red is good [期望DP]
Red is good Time Limit: 10 Sec Memory Limit: 64 MB[Submit][Status][Discuss] Description 桌面上有R张红牌和B张 ...
- NGINX: 反向代理 websocket
参考: [ Using multiple nodes ] [ Nginx 官网 WebSocket proxying ] 关于 websocket 的介绍可以看阮大大的这篇 [ WebSocket 教 ...