[JZOJ5131][SDOI省队集训2017]距离
来源:互联网 发布:美工海报设计兼职 编辑:程序博客网 时间:2024/05/17 22:42
题目描述
点分治
询问拆成四条到根的询问。
bfs一遍,处理出可持久化点分树。
查询直接查。
#include<cstdio>#include<algorithm>#include<cmath>#define fo(i,a,b) for(i=a;i<=b;i++)#define fd(i,a,b) for(i=a;i>=b;i--)using namespace std;typedef long long ll;const int maxn=400000+10,maxtot=maxn*30;int son[maxn],sx[maxn],fa[maxn];int rot[maxn],tree[maxtot][4];ll d1[maxn*20],d2[maxn*20];int s1[maxn*20],s2[maxn*20];int h[maxn],go[maxn*2],dis[maxn*2],next[maxn*2],p[maxn],bb[maxn],cc[maxn],zs[maxn];ll d[maxn][20];int belong[maxn][20],f[maxn][20],dep[maxn],zjy[maxn],sta[80];int size[maxn],a[maxn];int h2[maxn*2],g2[maxn*4],di2[maxn*4],n2[maxn*4];int ask[maxn];ll sum[maxn];bool bz[maxn];int i,j,k,l,r,t,nn,n,m,tot,top,cnt,num,czy;ll ans;int read(){ int x=0,f=1; char ch=getchar(); while (ch<'0'||ch>'9'){ if (ch=='-') f=-1; ch=getchar(); } while (ch>='0'&&ch<='9'){ x=x*10+ch-'0'; ch=getchar(); } return x*f;}void add(int x,int y,int z){ go[++tot]=y; dis[tot]=z; next[tot]=h[x]; h[x]=tot;}void add2(int x,int y,int z){ g2[++num]=y; di2[num]=z; n2[num]=h2[x]; h2[x]=num;}void link(int x,int y,int z){ add2(x,y,z); add2(y,x,z);}void new_build(int x,int y){ int t=h[x]; int i,j,k=0; while (t){ if (go[t]!=y) bb[++k]=go[t],cc[k]=dis[t]; t=next[t]; } if (k<=1){ fo(i,1,k) link(x,bb[i],cc[i]); } else{ fo(i,1,1) link(x,bb[i],cc[i]); j=x; fo(i,2,k){ ++n; zs[n]=x; link(j,n,0); j=n; link(j,bb[i],cc[i]); } } t=h[x]; while (t){ if (go[t]!=y) new_build(go[t],x); t=next[t]; }}void dfs(int x,int y){ f[x][0]=y; dep[x]=dep[y]+1; int t=h[x]; while (t){ if (go[t]!=y) dfs(go[t],x); t=next[t]; }}int lca(int x,int y){ if (dep[x]<dep[y]) swap(x,y); if (dep[x]!=dep[y]){ int j=zjy[dep[x]]; while (j>=0){ if (dep[f[x][j]]>=dep[y]) x=f[x][j]; j--; } } if (x==y) return x; int j=zjy[dep[x]]; while (j>=0){ if (f[x][j]!=f[y][j]){ x=f[x][j]; y=f[y][j]; } j--; } return f[x][0];}void travel(int x,int y){ a[++top]=x; int t=h[x]; size[x]=1; while (t){ if (go[t]!=y&&!bz[go[t]]){ travel(go[t],x); size[x]+=size[go[t]]; } t=next[t]; }}void dg(int x,int y,int z,int w){ belong[x][w]=z; int t=h[x]; while (t){ if (go[t]!=y&&!bz[go[t]]){ d[go[t]][w]=d[x][w]+(ll)dis[t]; dg(go[t],x,z,w); } t=next[t]; }}int solve(int x,int y){ top=0; travel(x,0); int i,j=x,k=0,t; while (1){ t=h[j]; while (t){ if (go[t]!=k&&!bz[go[t]]&&size[go[t]]>top/2){ k=j; j=go[t]; break; } t=next[t]; } if (!t) break; } if (!y) rot[0]=j; t=h[j]; while (t){ if (!bz[go[t]]){ //change(root[j],1,n,go[t],go[t]); d[go[t]][y]=dis[t]; dg(go[t],j,j,y); } t=next[t]; } bz[j]=1; belong[j][y]=j; t=h[j]; while (t){ if (!bz[go[t]]){ son[j]++; k=solve(go[t],y+1); sx[k]=son[j]; fa[k]=j; } t=next[t]; } return j;}void bfs(int x,int y){ int i,j,z=p[x],w=rot[y],u,v; if (x>nn){ rot[x]=rot[y]; } else{ tot++; rot[x]=tot; fo(i,0,20){ //root[tot]=root[w]; fo(j,1,3) tree[tot][j]=tree[w][j]; d1[tot]=d1[w]+d[z][i]; s1[tot]=s1[w]+1; if (i){ d2[tot]=d2[w]+d[z][i-1]; s2[tot]=s2[w]+1; } if (belong[z][i]==z) break; u=sx[belong[z][i+1]]; v=son[belong[z][i]]; //change(root[tot],1,v,u,tot+1); tree[tot][u]=tot+1; tot++; //w=query(root[w],1,v,u); w=tree[w][u]; } } int t=h[x]; while (t){ if (go[t]!=y) bfs(go[t],x); t=next[t]; }}void calc(int x,int f){ if (!x) return; int i,y=rot[x]; fo(i,0,20){ if (i){ ans-=f*d2[y]; ans-=(ll)f*s2[y]*d[k][i-1]; } ans+=f*d1[y]; ans+=(ll)f*s1[y]*d[k][i]; if (belong[k][i]==k) break; //y=query(root[y],1,son[belong[k][i]],sx[belong[k][i+1]]); y=tree[y][sx[belong[k][i+1]]]; }}void write(ll x){ if (!x){ putchar('0'); putchar('\n'); return; } top=0; while (x){ sta[++top]=x%10; x/=10; } while (top) putchar(sta[top--]+'0'); putchar('\n');}int main(){ freopen("dis.in","r",stdin);freopen("dis.out","w",stdout); czy=read(); n=read();m=read(); nn=n; fo(i,1,n-1){ j=read();k=read();l=read(); add(j,k,l);add(k,j,l); } new_build(1,0); fo(i,1,n) h[i]=h2[i]; fo(i,1,num){ go[i]=g2[i]; dis[i]=di2[i]; next[i]=n2[i]; } dfs(1,0); fo(i,1,n) zjy[i]=floor(log(i)/log(2)); fo(j,1,zjy[n]) fo(i,1,n) f[i][j]=f[f[i][j-1]][j-1]; fo(i,1,nn) p[i]=read(); tot=top=cnt=0; solve(1,0); fo(i,1,n) if (sx[i]) tree[fa[i]][sx[i]]=i; tot=n; fo(i,1,nn) zs[i]=i; bfs(1,0); while (m--){ l=read();r=read();k=read(); l^=(czy*ans);r^=(czy*ans);k^=(czy*ans); ans=0; calc(l,1); calc(r,1); j=zs[lca(l,r)]; calc(j,-1); j=zs[f[j][0]]; calc(j,-1); write(ans); }}
阅读全文
0 0
- [JZOJ5131][SDOI省队集训2017]距离
- [bzoj4927][SDOI省队集训2017]diyiti
- [bzoj4928][SDOI省队集训2017]dierti
- [bzoj4930][SDOI省队集训2017]棋盘
- [bzoj4931][SDOI省队集训2017]塔
- [JZOJ5129][SDOI省队集训2017]字符串
- [JZOJ5133][SDOI省队集训2017]重建
- [JZOJ5136][SDOI省队集训2017]重排
- [JZOJ5130][51nod1446][SDOI省队集训2017]苹果树
- [JZOJ5132][SDOI省队集训2017]子序列
- [JZOJ5134][SDOI省队集训2017]三元组
- [JZOJ5135][SDOI省队集训2017]逆序对
- [JZOJ5137][SDOI省队集训2017][bzoj4842]养猫
- 【SDOI省队集训题】棋盘(最小费用流)
- 【SDOI省队集训题】pair(线段树+二分)
- JZOJ 5489. 【清华集训2017模拟11.28】海明距离
- JZOJ 5489. 【清华集训2017模拟11.28】海明距离
- JZOJ5489. 【清华集训2017模拟11.28】海明距离
- it oracle 入门级 体系介绍
- FUNDAMENTAL Unit04 循环结构(while、do-while、for)
- android热插件,热更新,热修复,模块化
- iscsi
- 行列式求值
- [JZOJ5131][SDOI省队集训2017]距离
- 已安装 SQL Server 2005 Express 工具。若要继续,请删除 SQL Server 2005 Express 工具
- 一个文件实现安卓滚轮选择控件
- 通讯录(自己写strcpy,strcmp)
- 自己总结的面向对象
- 基于射频CC2520 实现的ZigBee 通信设计
- (源码阅读)源码分析之AsyncTask
- Android共享元素场景切换动画的实现
- 1432: [ZJOI2009]Function