BZOJ 3626 [LNOI2014]LCA
2016-07-13 19:31
309 查看
给出一个n个节点的有根树。有q次询问,求在[l,r]区间内的每个节点i与z的最近公共祖先的深度之和)。
共5组数据,n与q的规模分别为10000,20000,30000,40000,50000。
树链剖分+BIT
PS:用BIT求区间和非常赞
共5组数据,n与q的规模分别为10000,20000,30000,40000,50000。
树链剖分+BIT
PS:用BIT求区间和非常赞
#include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int maxn=50005; void rd(int &r){ r=0;char c; while(c=getchar(),c<48); do r=r*10+(c^48); while(c=getchar(),c>47); } int n,Q; int last[maxn],ecnt; struct Edge{ int to,nxt; }edge[maxn<<1]; void ins(int u,int v){ edge[++ecnt]=(Edge){v,last[u]}; last[u]=ecnt; } int frm[maxn]; int head[maxn],qcnt; struct Query{ int id,w,nxt; }qury[maxn<<1]; void ins_(int id,int w,int to){ qury[++qcnt]=(Query){id,w,head[to]}; head[to]=qcnt; } int dfs_clock; int segID[maxn]; int sz[maxn]; int link[maxn],par[maxn]; void dfs(int x){ sz[x]=1; for(int i=last[x];i;i=edge[i].nxt){ int to=edge[i].to; par[to]=x; dfs(to); sz[x]+=sz[to]; } } void assign(int x,int f){ segID[x]=++dfs_clock; link[x]=f; int mx=0; for(int i=last[x];i;i=edge[i].nxt){ int to=edge[i].to; if(sz[to]>sz[mx]) mx=to; } if(!mx)return; assign(mx,f); for(int i=last[x];i;i=edge[i].nxt){ int to=edge[i].to; if(mx!=to) assign(to,to); } } struct SUM{ struct BIT{ int v[maxn]; void update(int x,int f){ for(;x<=n;x+=x&-x)v[x]+=f; } int query(int x){ int res=0; for(;x;x-=x&-x)res+=v[x]; return res; } }bit[2]; void update(int l,int r,int x){ bit[0].update(l,(1-l)*x); bit[0].update(r+1,r*x); bit[1].update(l,x); bit[1].update(r+1,-x); } int query(int l,int r){ int rsum=bit[1].query(r)*r+bit[0].query(r); int lsum=bit[1].query(l-1)*(l-1)+bit[0].query(l-1); return rsum-lsum; } }sum; void update(int x){ while(link[x]!=0){ sum.update(segID[link[x]],segID[x],1); x=par[link[x]]; } } int Ans[maxn]; void query(int y){ int id=qury[y].id; int x=frm[id]; int w=qury[y].w; while(link[x]!=0){ Ans[id]+=w*sum.query(segID[link[x]],segID[x]); x=par[link[x]]; } } void solve(){ dfs(1); assign(1,1); for(int i=1;i<=n;i++){ update(i); for(int j=head[i];j;j=qury[j].nxt) query(j); } } void input(){ rd(n);rd(Q); for(int u,i=2;i<=n;i++){ rd(u);++u; ins(u,i); } for(int l,r,i=1;i<=Q;i++){ rd(l);rd(r);rd(frm[i]); ++l;++r;++frm[i]; ins_(i,1,r); if(l!=1)ins_(i,-1,l-1); } } const int mod=201314; void output(){ for(int i=1;i<=Q;i++) printf("%d\n",Ans[i]%mod); } int main(){ input(); solve(); output(); return 0; }
相关文章推荐
- eclipse中maven插件配置
- UE4学习笔记: Gameplay Classes
- iOS面试常见问题
- URAL 1627 Join(生成树计数)
- LeetCode 83. Remove Duplicates from Sorted List
- (一) JavaScritpt 基础点
- python学习笔记-正则表达式提取指定关键字
- jzoj 1389. 【2012.02.25普及组】单词 结题报告
- changecolor
- 快速集成iOS基于RTMP的视频推流
- powerDesigner生成Html及Word
- 加div小练习
- [Leetcode]205. Isomorphic Strings
- 1_FPGA开发环境的搭建
- UE4学习笔记(八): 游戏框架
- Android Service完全解析,关于服务你所需知道的一切(上)
- AFNetWorking 请求头的配置
- MySQL传智播客--Lession31-Lession43笔记
- touch.js-drag
- java正则替换img标签中src值