[BJOI2017]树的难题

考虑点分治,然后问题转换成求过根节点的路径的最大值,这种东西一般性就是搞一个线段树然后每一次合并一下两个子树然后查最大值即可

其实我自己也不是很懂,这题确实很神仙

#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
#define re register
#define ll long long
inline int gi(){
    int f=1,sum=0;char ch=getchar();
    while(ch>'9' || ch<'0'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0' && ch<='9'){sum=(sum<<3)+(sum<<1)+ch-'0';ch=getchar();}
    return f*sum;
}
const int N=500010,Inf=1e9+10;
int n,m,l,r,f[N],rt,mx,tot,val[N],ans=-Inf;
struct node{
    int v,ls,rs;
}t[N*100];
struct edge{int v,c;bool operator<(const edge &b)const{return cg[N];
int siz[N],dep[N],used[N],cnt,dis[N];
void getroot(int u,int ff){
    siz[u]=1;int now=0;
    for(int j=0;j>1;
    if(pos<=mid)modify(t[o].ls,l,mid,pos,v);
    else modify(t[o].rs,mid+1,r,pos,v);
    pushup(o);
}
int query(int o,int l,int r,int ql,int qr){
    if(!o)return -Inf;
    if(ql<=l && r<=qr)return t[o].v;
    int mid=(l+r)>>1,ret=-Inf;
    if(ql<=mid)ret=max(ret,query(t[o].ls,l,mid,ql,qr));
    if(qr>mid)ret=max(ret,query(t[o].rs,mid+1,r,ql,qr));
    return ret;
}
int merge(int x,int y,int l,int r){
    if(!x || !y)return x+y;
    if(l==r){t[x].v=max(t[x].v,t[y].v);return x;}
    int mid=(l+r)>>1;
    t[x].ls=merge(t[x].ls,t[y].ls,l,mid);
    t[x].rs=merge(t[x].rs,t[y].rs,mid+1,r);
    pushup(x);return x;
}
int hd,tl,q[N],vis[N],pre[N];
void bfs(int s,int C){
    vis[s]=1;q[hd=tl=1]=s;pre[s]=C;
    while(hd<=tl){
        int u=q[hd++];
        for(int i=0;i

转载于:https://www.cnblogs.com/mleautomaton/p/11167594.html

你可能感兴趣的:([BJOI2017]树的难题)