ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

bzoj3307: 雨天的尾巴

2019-02-01 11:40:43  阅读:270  来源: 互联网

标签:int 尾巴 tr dep bzoj3307 雨天 maxn now mx


Star_Feel大爷是最强的

这道题我的想法是把每种数字分开做,然后再合并

现在不知道为什么就写了这种树上差分+下标是数字的线段树合并(其实都一样)

那就这样吧

#include<cstdio>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>

#define mid (ql+qr)/2
using namespace std;
const int _=1e2;
const int maxn=1e5+_;
const int bit=30;

//---------------------------------------def-----------------------------------------------------

struct node
{
    int x,y,next;
}a[2*maxn];int len,last[maxn];
void ins(int x,int y)
{
    len++;
    a[len].x=x;a[len].y=y;
    a[len].next=last[x];last[x]=len;
}
int Bin[bit],f[bit][maxn],dep[maxn];
void dfs(int x)
{
    for(int i=1;dep[x]>=Bin[i];i++)f[i][x]=f[i-1][f[i-1][x]];
    for(int k=last[x];k;k=a[k].next)
    {
        int y=a[k].y;
        if(y!=f[0][x])
        {
            f[0][y]=x;
            dep[y]=dep[x]+1;
            dfs(y);
        }
    }
}
int LCA(int x,int y)
{
    if(dep[x]<dep[y])swap(x,y);
    for(int i=25;i>=0;i--)
        if(dep[x]-dep[y]>=Bin[i])x=f[i][x];
    if(x==y)return x;
    
    for(int i=25;i>=0;i--)
        if(dep[x]>=Bin[i]&&f[i][x]!=f[i][y])x=f[i][x],y=f[i][y];
    return f[0][x];
}

//---------------------------------------prepare-----------------------------------------------------

struct trnode
{
    int lc,rc,mx,id;
}tr[maxn*60];int trlen,rt[maxn];
void update(int now)
{
    int lc=tr[now].lc,rc=tr[now].rc;
    if(tr[lc].mx>=tr[rc].mx||rc==0)
        tr[now].mx=tr[lc].mx,tr[now].id=tr[lc].id;
    else
        tr[now].mx=tr[rc].mx,tr[now].id=tr[rc].id;
}
//~~~~~~~~~~~~~~~~~in~~~~~~~~~~~~~~~~~~~~

int change(int now,int ql,int qr,int p,int d)
{
    if(now==0)now=++trlen,tr[now].mx=ql==qr?0:-(1<<30);
    if(ql==qr){tr[now].mx+=d;tr[now].id=p;return now;}
    if(p<=mid)tr[now].lc=change(tr[now].lc,ql,mid,p,d);
    else tr[now].rc=change(tr[now].rc,mid+1,qr,p,d);
    update(now);return now;
}
int merge(int x,int y,int ql,int qr)
{
    if(x==0||y==0)return x+y;
    if(ql==qr){tr[x].mx+=tr[y].mx;return x;}
    tr[x].lc=merge(tr[x].lc,tr[y].lc,ql,mid);
    tr[x].rc=merge(tr[x].rc,tr[y].rc,mid+1,qr);
    update(x);return x;
}
//~~~~~~~~~~~~~~~~~out~~~~~~~~~~~~~~~~~~~~

//---------------------------------------segtree-----------------------------------------------------

struct query{int x,y,p;}q[maxn];
int lslen,ls[maxn];
int as[maxn];
void solve(int x)
{
    for(int k=last[x];k;k=a[k].next)
    {
        int y=a[k].y;
        if(y!=f[0][x])
        {
            solve(y);
            rt[x]=merge(rt[x],rt[y],1,lslen);
        }
    }
    as[x]=ls[tr[rt[x]].id];
}
int main()
{
    int n,m,x,y,p;
    scanf("%d%d",&n,&m); len=1;
    for(int i=1;i<n;i++)
    {
        scanf("%d%d",&x,&y);
        ins(x,y),ins(y,x);
    }
    Bin[0]=1;for(int i=1;i<=25;i++)Bin[i]=Bin[i-1]*2;
    dfs(1);
    
    for(int i=1;i<=m;i++)
        scanf("%d%d%d",&q[i].x,&q[i].y,&q[i].p),ls[++lslen]=q[i].p;
    sort(ls+1,ls+lslen+1);
    lslen=unique(ls+1,ls+lslen+1)-ls-1;
    for(int i=1;i<=m;i++)
        q[i].p=lower_bound(ls+1,ls+lslen+1,q[i].p)-ls;
    
    trlen=0;
    for(int i=1;i<=m;i++)
    {
        x=q[i].x,y=q[i].y,p=q[i].p;
        int lca=LCA(x,y);
        rt[x]=change(rt[x],1,lslen,p,1);
        rt[y]=change(rt[y],1,lslen,p,1);
        rt[lca]=change(rt[lca],1,lslen,p,-1);
        if(lca!=1)rt[f[0][lca]]=change(rt[f[0][lca]],1,lslen,p,-1);
    }
    solve(1);
    for(int i=1;i<=n;i++)printf("%d\n",as[i]);
    
    return 0;
}

 

标签:int,尾巴,tr,dep,bzoj3307,雨天,maxn,now,mx
来源: https://www.cnblogs.com/AKCqhzdy/p/10345251.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有