hihocoder 1381 Little Y's Tree

原创 2018年04月16日 21:42:14

http://www.elijahqi.win/archives/3110
Time Limit:24000ms
Case Time Limit:4000ms
Memory Limit:512MB
Description
Little Y has a tree of n nodes with each edge having a positive weight.

Little J has q queries, each time he will delete k edges in the tree.

Then the tree is splitted into k+1 connected componets.

Little J wants to know the sum of the distance of farthest pair of points in each connected components.

(0 when one component only has one node.)

Each query is independent with each other. This means each query is based on the original tree.

Input
First line with an integer n, indicating the number of nodes.

Then following n-1 lines, the i-th line with three integers ui, vi, wi, indicating the i-th edge weighted wi connects ui and vi.

Then following one line with an integer q, indicating the number of queries.

For each query, the first line with an integer k, then following one line with k integers, indicating the id of the deleted edges.

1<=n,q,Σk<=105,1<=w<=109

Output
For each query, output one line with an integer indicating the sum.

Sample Input
5
1 2 2
2 3 3
2 4 4
4 5 2
3
4 1 2 3 4
1 4
2 2 3
Sample Output
0
7
4
要求动态维护树的直径

首先按照dfs序将整棵树映射到线段树上 针对线段树每个点维护一下子树的信息 维护这个点内直径的起点和终点 还有直径的长度 那么将两个节点合并起来的操作就是枚举一下四个端点分别计算大小 然后最后再算一遍和他们各自内部的值一共六种情况 取max那么可能会说 线段树所管辖的这段区间在树上不连续怎么办 那么很显然询问会询问的都是连续的区间 所以无所谓了

那么最后求答案 怎么求 因为题目给的是限制最多切k条边 因为切的边只会划分出子树 子树在dfs序上又是连续的区间 那么显然最后最多被分成了2*k+1的区间 那么我们针对这些区间分别求即可怎么求 大致来说就是首先判断一个区间 我是否被划分子树了 如果被划分子树了就递归去求 然后剩余的部分再一个循环 暴力将他们拼起来求答案 因为有总区间数的性质 保证了复杂度

#include<cstdio>
#include<cctype>
#include<algorithm>
#define lc (x<<1)
#define rc (x<<1|1)
#define ll long long
using namespace std;
inline char gc(){
    static char now[1<<16],*S,*T;
    if (T==S){T=(S=now)+fread(now,1,1<<16,stdin);if (T==S) return EOF;}
    return *S++;
}
inline int read(){
    int x=0,f=1;char ch=gc();
    while(!isdigit(ch)) {if(ch=='-') f=-1;ch=gc();}
    while(isdigit(ch)) x=x*10+ch-'0',ch=gc();
    return x*f;
}
const int N=1e5+20;
struct node{
    int y,next,z;
}data[N<<1];
struct node1{
    int x,y;ll dis;
    node1(){dis=-1;}
    node1(int _x,int _y,ll _dis){x=_x;y=_y;dis=_dis;}
}tree[N<<2];
int mn[N<<1][20],Log[N<<1],n,num=1,cnt,dep[N],pos[N],h[N],in[N],out[N],b[N<<1],k,a[N],dfn[N],now;
ll dis[N],ans;
inline void dfs(int x,int fa){
    mn[++num][0]=x;pos[x]=num;in[x]=++cnt;dfn[cnt]=x;
    for (int i=h[x];i;i=data[i].next){
        int y=data[i].y;if (y==fa) continue;dep[y]=dep[x]+1;
        dis[y]=dis[x]+data[i].z;b[i>>1]=y;dfs(y,x);mn[++num][0]=x;
    }out[x]=cnt;
}
inline void init(){
    for (int j=1;j<=Log[num];++j)
        for (int i=1;i+(1<<j)-1<=num;++i)
            mn[i][j]=dep[mn[i][j-1]]<dep[mn[i+(1<<j-1)][j-1]]?mn[i][j-1]:mn[i+(1<<j-1)][j-1];
}
inline int lca(int x,int y){
    x=pos[x];y=pos[y];if (x>y) swap(x,y);int t=Log[y-x+1];
    return dep[mn[x][t]]<dep[mn[y-(1<<t)+1][t]]?mn[x][t]:mn[y-(1<<t)+1][t];
}
inline ll calc(int x,int y){
    return dis[x]+dis[y]-(dis[lca(x,y)]<<1);
}
inline node1 merge(const node1 &ls,const node1 &rs){
    if (ls.dis==-1) return rs;if (rs.dis==-1) return ls;
    static int nx,ny,lx,ly,rx,ry;static ll tmp1,tmp2,tmp3,tmp4,mx;mx=0;
    lx=ls.x;ly=ls.y;rx=rs.x,ry=rs.y;
    if (ls.dis>mx) nx=lx,ny=ly,mx=ls.dis;
    if (rs.dis>mx) nx=rx,ny=ry,mx=rs.dis;
    tmp1=calc(lx,rx);tmp2=calc(lx,ry);tmp3=calc(ly,rx);tmp4=calc(ly,ry);
    if (tmp1>mx) nx=lx,ny=rx,mx=tmp1;if (tmp2>mx) nx=lx,ny=ry,mx=tmp2;
    if (tmp3>mx) nx=ly,ny=rx,mx=tmp3;if (tmp4>mx) nx=ly,ny=ry,mx=tmp4;
    return (node1){nx,ny,mx};
}
inline void build(int x,int l,int r){
    if (l==r) {tree[x].x=tree[x].y=dfn[l];tree[x].dis=0;return;}int mid=l+r>>1;
    build(lc,l,mid);build(rc,mid+1,r);tree[x]=merge(tree[lc],tree[rc]);
}
inline node1 query(int x,int l,int r,int l1,int r1){
    if(l1<=l&&r1>=r) return tree[x];int mid=l+r>>1;node1 tmp;
    if (l1<=mid) tmp=merge(tmp,query(lc,l,mid,l1,r1));
    if (r1>mid) tmp=merge(tmp,query(rc,mid+1,r,l1,r1));return tmp;
}
inline bool cmp(const int &a,const int &b){return in[a]<in[b];}
inline void solve(int l,int r){node1 tmp;int L=l;
    while(now<=k&&in[a[now]]>=l&&out[a[now]]<=r){int t;
        t=now++;solve(in[a[t]],out[a[t]]);
        if(L<=in[a[t]]-1) tmp=merge(tmp,query(1,1,n,L,in[a[t]]-1));
        L=out[a[t]]+1;
    }if (L<=r) tmp=merge(tmp,query(1,1,n,L,r));ans+=tmp.dis;
}
inline void print(int x,int l,int r){
    if (l==r) {printf("%d %d %d %d %d\n",l,r,tree[x].x,tree[x].y,tree[x].dis);return;}
    int mid=l+r>>1;print(lc,l,mid);
    printf("%d %d %d %d %lld\n",l,r,tree[x].x,tree[x].y,tree[x].dis);
    print(rc,mid+1,r);
}
int main(){
//  freopen("hiho1381.in","r",stdin);
//  freopen("12.out","w",stdout);
    n=read();Log[0]=-1;
    for (int i=1;i<=n<<1;++i) Log[i]=Log[i>>1]+1;
    for (int i=1;i<n;++i){static int x,y,z;
        x=read(),y=read();z=read();
        data[++num].y=y;data[num].next=h[x];h[x]=num;data[num].z=z;
        data[++num].y=x;data[num].next=h[y];h[y]=num;data[num].z=z;
    }num=0;dfs(1,1);init();build(1,1,n);int q=read();
    while(q--){k=read();
        for (int i=1;i<=k;++i) a[i]=b[read()];
        sort(a+1,a+k+1,cmp);now=1;
        ans=0;solve(1,n);printf("%lld\n",ans);
    }
    return 0;
}
版权声明:辣鸡蒟蒻的blog https://blog.csdn.net/elijahqi/article/details/79967117

hihocoder-#1338 : A Game

http://hihocoder.com/problemset/problem/1338?sid=827401 #1338 : A Game 时间限制:10000ms ...
  • zmq570235977
  • zmq570235977
  • 2016-07-18 17:15:28
  • 457

[点分治] HihoCoder #1462 Challenge 26 Rikka with Tree IV

考试的时候打死想不出来 然后Evan在边上随口就切掉了... 直接搬题解吧 考虑包含k 个点的链,可以得出任意距离不超过k...
  • u014609452
  • u014609452
  • 2017-01-03 16:16:09
  • 446

hihoCoder 1338 : A Game(dp)

A GameTime limit:1000ms Memory limit:256MB Problem DescriptionLittle Hi and Little Ho are playing a...
  • xp731574722
  • xp731574722
  • 2017-10-21 22:18:53
  • 92

hihoCoder #1490 Tree Restoration 一直RE,求指导

题目如下,我自己还设计了两个测试样例,样例都通过了,但是提交一直RE,求大神指导。 题目给的 8 3 5 1 3 4 1 2 3 4 5 6 7 8 3 5 6 7 8 0 3 3 3 3 3 ...
  • dalangzhonghangxing
  • dalangzhonghangxing
  • 2017-04-01 11:01:38
  • 620

Hdu 3830 Checkers

Checkers Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 125536/65536 K (Java/Others) Tota...
  • modiz
  • modiz
  • 2014-11-17 20:36:00
  • 557

Freckles

Description In an episode of the Dick Van Dyke show, little Richie connects the freckles on his Dads...
  • nbu_james
  • nbu_james
  • 2009-09-30 11:32:00
  • 611

hihocoder #1500 : EL SUENO 树DP

#1500 : EL SUENO 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 In a video game, Li...
  • viphong
  • viphong
  • 2017-04-13 23:12:35
  • 405

hihocoder #1499 : A Box of Coins 贪心

描述 Little Hi has a box which consists of 2xN cells as illustrated below. +----+----+----+----+----+-...
  • viphong
  • viphong
  • 2017-04-13 21:47:50
  • 842

hihoCoder #1490 : Tree Restoration 微软2017在线笔试题

题意 给你一棵树,已知其中全部节点的编号(1~n),节点所在层次,节点在该层从左到右是第几个节点,叶子节点编号以及叶子节点间的距离,但不知节点之间的边信息,要求重构这棵树,输出每个节点的父亲节点。 思...
  • luke2834
  • luke2834
  • 2017-04-01 11:38:34
  • 967

Fermat's little theorem(费马小定理)

If p is prime, then for every a >= 1 and a 如果p是质数,那么对于所有的 大于1,小于p的 a,都有 a 的 p-1 次方 除以 p 的余数为1。 这个定理...
  • topasstem8
  • topasstem8
  • 2013-09-24 08:47:57
  • 2217
收藏助手
不良信息举报
您举报文章:hihocoder 1381 Little Y's Tree
举报原因:
原因补充:

(最多只允许输入30个字)