bzoj4012(动态点分治+卡常数)
2017-02-08 23:06
337 查看
这是一种类型的动态点分治
动态点分治,关键还是要在均摊n的空间复杂度内存下所有东西。这个就要充分利用stl,比如vector
每一个点存以这个点为根点分治的信息。
对于询问一个点的路径时,就是沿着点分治树,不断朝fa走,每走一层统计一下,因为分治树可以保证在log层内,时间复杂度同阶
卡常数
无优化:43848ms
优化一:取模优化(x-=mod 代替 % ) + 循环展开+ 一部分inline :43612ms
第三次:将i++改为++i:速度稍减慢,dfs(int &u)占位符加速也没有体现出来
优化不下去了
动态点分治,关键还是要在均摊n的空间复杂度内存下所有东西。这个就要充分利用stl,比如vector
每一个点存以这个点为根点分治的信息。
对于询问一个点的路径时,就是沿着点分治树,不断朝fa走,每走一层统计一下,因为分治树可以保证在log层内,时间复杂度同阶
卡常数
无优化:43848ms
优化一:取模优化(x-=mod 代替 % ) + 循环展开+ 一部分inline :43612ms
第三次:将i++改为++i:速度稍减慢,dfs(int &u)占位符加速也没有体现出来
优化不下去了
#include<cmath> #include<cstring> #include<cstdlib> #include<algorithm> #include<cstdio> #include<queue> #include<vector> #include<utility> #define fi first #define se second #define pii pair<int,int> #define MK(a,b) make_pair((a),(b)) using namespace std; typedef long long ll; const int N=150005; inline int read() { int ans,f=1;char ch; while ((ch=getchar())<'0'||ch>'9') if (ch=='-') f=-1;ans=ch-'0'; while ((ch=getchar())>='0'&&ch<='9') ans=ans*10+ch-'0'; return ans*f; } int n,Q,A;ll ans; int U,L,R; ///////////////////// struct bian { int to[N*2],pre[N*2],dis[N*2],head ,tot; void addedge(int u,int v,int d) { to[++tot]=v;pre[tot]=head[u];head[u]=tot;dis[tot]=d; } }e; ////////////////////// int age ,fa ;ll dis ; struct aa { int num; vector< pair<int,pair<int,int> > >a; vector< pair<int,ll> > ch[3]; int f(int u) { int l=0,r=a.size()-1,mid,ans; while (l<=r) { mid=(l+r)>>1; if (a[mid].fi>=u) ans=mid,r=mid-1; else l=mid+1; } return ans; } int dis(int u) { return a[f(u)].se.se; } int id(int u) { return a[f(u)].se.fi; } void init() { sort(a.begin(),a.end()); for (int i=0;i<num;i++) { sort(ch[i].begin(),ch[i].end()); int sz=ch[i].size(); for (int j=1;j<sz;j++) ch[i][j].se+=ch[i][j-1].se; } } ll query(int u,int up) { int tid=id(u);ll tdis=dis(u),ans=0; for (int i=0;i<num;i++) if (tid!=i) { int pos=upper_bound(ch[i].begin(),ch[i].end(),MK(up,(ll)(1e16)))-ch[i].begin(); if (pos==0) continue; ans+=(ll)pos*tdis; ans+=ch[i][pos-1].se; } return ans; } }tt ; ///////////// int size ,sum,mi,rt; bool b ; void get_size(int u,int fat) { int v;size[u]=1; for (int i=e.head[u];i;i=e.pre[i]) { v=e.to[i]; if (!b[v]&&v!=fat) { get_size(v,u); size[u]+=size[v]; } } } void get_rt(int u,int fat) { int v,mx=sum-size[u]; for (int i=e.head[u];i;i=e.pre[i]) { v=e.to[i]; if (!b[v]&&v!=fat) { get_rt(v,u); mx=max(mx,size[v]); } } if (mx<mi) rt=u,mi=mx; } queue<int> q; void dfs2(int u,int fat,int d) { int v; dis[u]=d;q.push(u); for (int i=e.head[u];i;i=e.pre[i]) { v=e.to[i]; if (!b[v]&&v!=fat) dfs2(v,u,d+e.dis[i]); } } void work(int u) { int v,&num=tt[u].num; tt[u].a.push_back(MK(u,MK(-1,0))); for (int i=e.head[u];i;i=e.pre[i]) { v=e.to[i]; if (!b[v]) { dfs2(v,u,e.dis[i]); while (!q.empty()) { v=q.front();q.pop(); tt[u].a.push_back(MK(v,MK(num,dis[v]))); tt[u].ch[num].push_back(MK(age[v],dis[v])); } num++; } } tt[u].init(); } void dfs(int u,int fat) { get_size(u,0);sum=size[u];mi=1e7; get_rt(u,0);u=rt; b[u]=true;fa[u]=fat;work(u); for (int i=e.head[u];i;i=e.pre[i]) if (!b[e.to[i]]) dfs(e.to[i],u); } /////////////////////////////////////////// void init() { n=read(),Q=read(),A=read(); for (int i=1;i<=n;i++) age[i]=read(); int xx,yy,zz; for (int i=1;i<n;i++) { xx=read(),yy=read(),zz=read(); e.addedge(xx,yy,zz); e.addedge(yy,xx,zz); } dfs(1,0); } ll query(int u,int up) { if (up<0) return 0; ll ans=0; while (u) { if (age[u]<=up) ans+=tt[u].dis(U); ans+=tt[u].query(U,up),u=fa[u]; } return ans; } int main() { init(); for (int i=1;i<=Q;i++) { U=read(),L=read(),R=read(); L=(L+ans)%A,R=(R+ans)%A; if (L>R) swap(L,R); ans= query(U,R)- query(U,L-1); printf("%lld\n",ans); ans=ans%A; } return 0; }
相关文章推荐
- [BZOJ4012][HNOI2015]开店(动态点分治)
- BZOJ4012 [HNOI2015]开店 【动态点分治 + splay】
- BZOJ4012【动态点分治】
- BZOJ 4012 HNOI 2015 开店 动态点分治
- bzoj4012 [HNOI2015]开店(动态点分治+二分+STL/树链剖分+主席树)
- [BZOJ4012][HNOI2015]开店(动态点分治,树链剖分)
- bzoj4012开店 动态点分治
- BZOJ-4012 开店(动态树分治)
- [BZOJ4372][动态树分治(点分树)][动态开点线段树]烁烁的游戏
- [BZOJ1492][NOI2007][斜率优化][动态凸包][DP][分治]货币兑换cash
- [BZOJ3730]震波(动态点分治)
- BZOJ 3924: [Zjoi2015]幻想乡战略游戏(动态点分治)
- [动态MST] [CDQ分治] BZOJ2001: [Hnoi2010]City 城市建设
- BZOJ 1095 [ZJOI2007]Hide 捉迷藏 ——动态点分治
- 【BZOJ3295】动态逆序对,CDQ分治/BIT套权值线段树
- BZOJ 1095 Hide 捉迷藏 详解(动态点分治 堆维护)
- 【bzoj3924】[Zjoi2015]幻想乡战略游戏 动态点分治
- 【BZOJ3295】动态逆序对(CQOI2011)-CDQ分治:三维偏序
- [DP 斜率优化 CDQ分治||动态维护凸包] BZOJ 1492 [NOI2007]货币兑换Cash
- bzoj3295 [Cqoi2011]动态逆序对(CDQ分治)