分块法 hdu4858 项目管理
来源:互联网 发布:云计算公司排名 编辑:程序博客网 时间:2024/06/05 06:39
一看到这题,首先会觉得非常像单点更新的线段树,但是却不怎么好操作
然后应该往分块的方向去想
因为只有m条边,所以所有点的度总和是2m,那么设度数>=sqrt(m)的点叫做重点,反之则是轻点
那么重点的个数<=2m/sqrt(m)=2sqrt(m)
设A[i]表示该点的值,sum[i]表示该点周围相连的点的A[i]之和
构造图的时候也有技巧,对于一条边(u,v)
如果u是轻点,直接添加(u,v)这条边 //因为边数不会超过sqrt(m)条
如果u是重点,那么v也是重点时候,才添加(u,v)这条边 //因为重点个数小于2sqrt(m),所以这里添加的边也不算特别多
更新时
对于每个点,先更新自己,A[u]+=d,遍历其所有的边,使sum[v]+=d
实际上本来如果v是轻点,是可以不用操作的,但是也无所谓啦,反正只有u也是轻点的时候,v才可能是轻点,但是u的边数已经很小了,加不加判断都无所谓
操作了也并不会影响答案,因为如果i是轻点,sum[i]是没用的,等下继续讲
查询时
如果x是重点,由之前的构图和更新能知道,对于任意v是重点边,都是添加在图里面的,所以sum[x]就是答案
如果x是轻点,实际上sum[x]是没意义的,但是与x连接的边数<=sqrt(m),所以直接枚举所有周围的点,积累周围点的A值即可
#include<cstdio>#include<cstring>#include<cstdlib>#include<cmath>#include<vector>#include<algorithm>using namespace std;typedef long long LL;const int mod=1e9+7;const int MX=100100+5;const int INF=0x3f3f3f3f;struct Edge{ int u,v;}E[MX];int n,m,unit,Q;int P[MX],sum[MX],A[MX];vector<int>G[MX];void update(int x,int d){ A[x]+=d; for(int i=0;i<G[x].size();i++){ int nxt=G[x][i]; sum[nxt]+=d; }}int query(int x){ if(P[x]<unit){ sum[x]=0; for(int i=0;i<G[x].size();i++){ int nxt=G[x][i]; sum[x]+=A[nxt]; } return sum[x]; }else{ return sum[x]; }}int main(){ int T; scanf("%d",&T); while(T--){ scanf("%d%d",&n,&m); memset(A,0,sizeof(A)); memset(P,0,sizeof(P)); memset(sum,0,sizeof(sum)); for(int i=1;i<=n;i++) G[i].clear(); for(int i=1;i<=m;i++){ scanf("%d%d",&E[i].u,&E[i].v); P[E[i].u]++; P[E[i].v]++; } unit=sqrt(m+0.5); for(int i=1;i<=m;i++){ int u=E[i].u,v=E[i].v; if(P[u]<unit) G[u].push_back(v); else if(P[v]>=unit) G[u].push_back(v); if(P[v]<unit) G[v].push_back(u); else if(P[u]>=unit) G[v].push_back(u); } scanf("%d",&Q); while(Q--){ int cmd,a,b; scanf("%d",&cmd); if(cmd==0){ scanf("%d%d",&a,&b); update(a,b); } else{ scanf("%d",&a); printf("%d\n",query(a)); } } } return 0;}
0 0
- 分块法 hdu4858 项目管理
- HDU4858 项目管理 (分块)
- 分块法 hdu4858 项目管理 1月5日
- hdu4858 项目管理
- 【暴力】HDU4858项目管理
- HDU4858 项目管理
- HDU4858-项目管理
- HDU4858 项目管理【图论】【待】
- hdu4858 项目管理 bestcoder round1 B
- 【简单枚举】HDU4858项目管理【BestCoder Round #1】
- hdu4858
- 【分块】 HDOJ 4858 项目管理
- [hdu 4858项目管理]分块
- hdu 4858 项目管理 分块
- HDU 4858 项目管理(点分块)
- 分块式内存管理原理
- 第十四周项目--分块查找
- HDU4858美素数
- 社説 20150701 骨太方針決定 アベノミクスを深化させよ
- Socket通信之BIO(同步阻塞IO)、PAIO(伪异步阻塞IO)、NIO(异步非阻塞IO)、AIO(异步非阻塞IO)、netty5之IO
- 错误:the image set name is used by multiply image sets
- 如何看:泊松分布???
- mysql取出两者不一致的数据
- 分块法 hdu4858 项目管理
- web.input()与web.data()函数比较
- java线程的生命周期有哪些
- java反射机制
- 实现ppt转pdf的方法
- QWidget: Must construct a QApplication before a QWidget
- [leetcode] 109.Convert Sorted List to Binary Search Tree
- 系统服务(daemons)
- 支持上下拉刷新的RecycleView,基于androidPullToRefresh