bzoj4012: [HNOI2015]开店
来源:互联网 发布:java 类中调用打印日志 编辑:程序博客网 时间:2024/05/16 00:49
题目
bzoj4012
题意
给定一棵边带权,点也带权的树,每次询问所有点权在[l,r]间的点到节点u的距离和。满足 n<=150000,Q<=200000。强制在线。
思路
两点间的距离
下面贴代码:时间:11340 MS 空间:156288 KB。
#include<cstdio>#include<cstring>#include<algorithm>#include<iostream>#include<utility>using namespace std;#define maxn 150010typedef long long ll;struct edge{int x,d,next;}e[maxn*2];struct node{int ls,rs,dfn,tag;ll sum;}t[maxn*40];typedef pair<int ,int>par;par mon[maxn];int n,A,Q,tot,dfn,sum,num,x,y,z,first[maxn]; int f[maxn],son[maxn],size[maxn],top[maxn],pos[maxn]; //树剖 int sumN[maxn],dis[maxn],root[maxn];ll sumdis[maxn],ans;void add(int x,int y,int z){ e[++tot].x=y; e[tot].d=z; e[tot].next=first[x]; first[x]=tot;}void dfs1(int x,int fa){ f[x]=fa; size[x]=1; for(int i=first[x];i;i=e[i].next) if(e[i].x!=fa){ dis[e[i].x]=dis[x]+e[i].d; dfs1(e[i].x,x); size[x]+=size[e[i].x]; if(size[e[i].x]>size[son[x]])son[x]=e[i].x; }}void dfs2(int x,int y){ pos[x]=++dfn; sumN[dfn]=dis[x]-dis[f[x]]; top[x]=y; if(son[x])dfs2(son[x],y); for(int i=first[x];i;i=e[i].next) if(e[i].x!=f[x]&&e[i].x!=son[x])dfs2(e[i].x,e[i].x);}void change(int ti,int &k,int l,int r,int a,int b){ if(t[k].dfn!=ti){ t[++num]=t[k]; k=num; t[k].dfn=ti; } if(b==r&&a==l){ t[k].tag++; return; } t[k].sum+=sumN[b]-sumN[a-1]; int mid=(l+r)>>1; if(b<=mid)change(ti,t[k].ls,l,mid,a,b); else if(a>mid)change(ti,t[k].rs,mid+1,r,a,b); else change(ti,t[k].ls,l,mid,a,mid),change(ti,t[k].rs,mid+1,r,mid+1,b);}ll ask(int l,int r,int a,int b,int k){ ll tmp=t[k].tag*(ll)(sumN[b]-sumN[a-1]); if(l==a&&r==b)return tmp+t[k].sum; int mid=(l+r)>>1; if(b<=mid)return tmp+ask(l,mid,a,b,t[k].ls); else if(a>mid)return tmp+ask(mid+1,r,a,b,t[k].rs); else return tmp+ask(l,mid,a,mid,t[k].ls)+ask(mid+1,r,mid+1,b,t[k].rs);}void insert(int x,int ti){ root[ti]=root[ti-1]; while(x){ change(ti,root[ti],1,n,pos[top[x]],pos[x]); x=f[top[x]]; }}ll solve(int x,int ti){ ll tmp=0; while(x){ tmp+=ask(1,n,pos[top[x]],pos[x],root[ti]); x=f[top[x]]; } return tmp;}char BUF[1000010],*buf,*end;#define getch() (buf==end?fread(BUF,1,1000000,stdin),buf=BUF,end=buf+1000000,*(buf++):*(buf++))template <class T>void read(T &x){ char c=getch(); for(;c<'0'||c>'9';c=getch()); for(x=0;'0'<=c&&c<='9';c=getch())x=x*10+c-'0';} int main(){ read(n); read(Q); read(A); for(int i=1;i<=n;i++)read(x),mon[i]=make_pair(x,i); sort(mon+1,mon+n+1); for(int i=1;i<n;i++){ read(x); read(y); read(z); add(x,y,z); add(y,x,z); } dfs1(1,0); dfs2(1,1); for(int i=1;i<=n;i++)sumdis[i]=sumdis[i-1]+dis[mon[i].second]; for(int i=2;i<=dfn;i++)sumN[i]+=sumN[i-1]; for(int i=1;i<=n;i++)insert(mon[i].second,i); for(int i=1;i<=Q;i++){ read(z); read(x); read(y); x=((ll)x+ans)%A; y=((ll)y+ans)%A; if(x>y)swap(x,y); x=lower_bound(mon+1,mon+1+n,make_pair(x,0))-mon; y=upper_bound(mon+1,mon+1+n,make_pair(y,1000000000))-mon-1; ans=(ll)(y-x+1)*(ll)dis[z]+sumdis[y]-sumdis[x-1]-2*(solve(z,y)-solve(z,x-1)); printf("%lld\n",ans); } return 0;}
0 0
- bzoj4012: [HNOI2015]开店
- bzoj4012: [HNOI2015]开店
- BZOJ4012: [HNOI2015]开店
- [动态树分治] BZOJ4012 [HNOI2015]开店
- [BZOJ4012][HNOI2015]开店-树链剖分-主席树
- BZOJ4012: [HNOI2015]开店 重链剖分 可持久化线段树
- bzoj4012开店
- 【HNOI2015】开店
- HNOI2015 开店
- HNOI2015开店
- 【HNOI2015】开店
- bzoj4012 开店 树链剖分&主席树
- bzoj4012开店 动态点分治
- [BZOJ4012]开店 点分治+STL
- BZOJ 4012: [HNOI2015]开店
- 【HNOI2015】开店(shop)
- [HNOI2015][JZOJ4068]开店
- 4012: [HNOI2015]开店
- Mouse Without Border 无法安装问题
- awk定位列数不足的数据
- hdu 2568 前进
- leetcode之Sort Colors
- 有关PMP考试成绩如何查询
- bzoj4012: [HNOI2015]开店
- MyEclipse/Eclipse安装插件的几种方式
- 三级分销系统
- Android开发中的MVP架构
- MFC 动态创建控件
- 3-6-汉诺塔(Hanoi Tower)问题-栈和队列-第3章-《数据结构》课本源码-严蔚敏吴伟民版
- java7新特性介绍
- [cocos2dx]我的学习记录
- sunxi分区那些事儿