P4556 [Vani有约会]雨天的尾巴

思路

每个节点维护一课线段树(当然是动态开点)
线段树的作用是统计这个节点有多少种粮食型号,以及最多的粮食型号
然后树上差分,u和v点 +1,lca(u,v)和f[lca(u,v)] -1(不显然就画图喽)
并不用转化为dfs序
只需要dfs一边,自底向上合并就好

优化

删除节点不必建树
因为在递归到他的时候一定是存在的
(要不 他还能减成负数吗、、)
但在一开始建树的时候就不一定存在了
所以记录下来就好

过程中的问题/疑问

这合并真的靠谱吗
如果两个线段树都是满二叉那不凉凉了

先引用博客大佬一段:
这样子做时间复杂度取决于重合节点个数
因为满二叉树的结点数是O(n)
对每个结点进行处理是O(logn)
最坏复杂度是O(nlogn),

看着很凉,但是一点也不凉(说出了什么b话)
假设一个为满二叉
最坏复杂度的情况一定是重合部分最多的时候
也就是每条链都是分开的(一条链子合并复杂度最坏为logn)
一次修改4个点,一共修改4n个点 (n,m同阶的话)
那复杂度就是4nlogn也就是nlogn了
平均每棵树4点,实际上也不会每次修改logn
Emma,应该是这样

错误

n并不是救济粮型号的范围
所以建树应该是1到10w而不是n
zz了,2333

代码

//¢¢£
#include <bits/stdc++.h>
#define FOR(i,a,b) for(int i=a;i<=b;++i)
using namespace std;
const int maxn=1e5+7;
const int N=1e5;
inline int read() {
    int x=0,f=1;char s=getchar();
    for(;s>'9'||s<'0';s=getchar()) if(s=='-') f=-1;
    for(;s>='0'&&s<='9';s=getchar()) x=x*10+s-'0';
    return x*f;
}
int n,m,ans[maxn],cnt,rt[maxn];
vector<int> delet[maxn];
int ch[maxn*50][2],ma[maxn*50],id[maxn*50];

//关于图 
struct edge {int v,nxt;}e[maxn<<1];
int head[maxn<<1],tot;
void add_edge(int u,int v) {e[++tot].v=v;e[tot].nxt=head[u];head[u]=tot;}

namespace LCA {
    int dep[maxn],st[maxn][21];
    void dfs(int u,int f) {
        for(int i=head[u];i;i=e[i].nxt) {
            int v=e[i].v;
            if(v==f) continue;
            dep[v]=dep[u]+1;
            st[v][0]=u;
            dfs(v,u);
        }
    }
    int lca(int x,int y) {
        if(dep[x]<dep[y]) swap(x,y);
        for(int i=20;i>=0;--i)
            if(dep[st[x][i]]>=dep[y])
                x=st[x][i];
        if(x==y) return x;
        for(int i=20;i>=0;--i)
            if(st[x][i]!=st[y][i])
                x=st[x][i],y=st[y][i];
        return st[x][0];
    }
    void init() {
        dep[1]=1;
        dfs(1,0);
        FOR(j,1,20) FOR(i,1,n)
        st[i][j]=st[st[i][j-1]][j-1];
    }
}

void pushup(int now) {
    ma[now]=max(ma[ch[now][0]],ma[ch[now][1]]);
    id[now]=ma[ch[now][0]]>=ma[ch[now][1]] ? id[ch[now][0]] : id[ch[now][1]];
    //加了=才会有题目中的优先级 
}
void build(int &now,int l,int r,int k,int up) {
    if(!now) now=++cnt;
    if(l==r) { 
        ma[now]+=up;
//      id[now]=!ma[now] ? 0 : l;
        return;
    }
    int mid=(l+r)>>1;
    if(k<=mid) build(ch[now][0],l,mid,k,up);
    else build(ch[now][1],mid+1,r,k,up);
    pushup(now);
}
int merge(int l,int r,int x,int y) {
    if(!x||!y) return x+y;
    if(l==r) {ma[x]+=ma[y];id[x]=l;return x;}
    int mid=(l+r)>>1;
    ch[x][0]=merge(l,mid,ch[x][0],ch[y][0]);
    ch[x][1]=merge(mid+1,r,ch[x][1],ch[y][1]);
    pushup(x);
    return x;   
}
void dfs(int u,int f) {
    for(int i=head[u];i;i=e[i].nxt) {
        int v=e[i].v;
        if(v==f) continue; 
        dfs(v,u);
        rt[u]=merge(1,N,rt[u],rt[v]);
    }
    for(vector<int>::iterator it=delet[u].begin();it!=delet[u].end();++it)
        build(rt[u],1,N,*it,-1);
    ans[u]=id[rt[u]];
}
int main() {
    n=read(),m=read();
    FOR(i,2,n) {
        int x=read(),y=read();
        add_edge(x,y),add_edge(y,x);
    }
    LCA::init(); 
    FOR(i,1,m) {
        int x=read(),y=read(),z=read();
        int tmp=LCA::lca(x,y);
        build(rt[x],1,N,z,1);
        build(rt[y],1,N,z,1);
        delet[tmp].push_back(z);
        delet[LCA::st[tmp][0]].push_back(z);
    }
    dfs(1,0);
    FOR(i,1,n) cout<<ans[i]<<"\n";
    return 0;
}
全部评论

相关推荐

09-29 16:59
已编辑
门头沟学院 Java
牛客96609213...:疯狂背刺,之前还明确设置截止日期,还有笔试,现在一帮人卡在复筛,他反而一边开启扩招,还给扩招的免笔试,真服了,你好歹先把复筛中的给处理了再说
投递大疆等公司10个岗位
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
正在热议
更多
# 你的mentor是什么样的人? #
3717次浏览 27人参与
# 你觉得mentor喜欢什么样的实习生 #
10077次浏览 283人参与
# 平安产险科技校招 #
2400次浏览 0人参与
# 帮我看看,领导说这话什么意思? #
6032次浏览 25人参与
# 没有家庭托举的我是怎么找工作的 #
12176次浏览 156人参与
# 怎么给家人解释你的工作? #
1337次浏览 16人参与
# 未岚大陆求职进展汇总 #
23792次浏览 111人参与
# 求职低谷期你是怎么度过的 #
5145次浏览 91人参与
# 26届秋招公司红黑榜 #
11674次浏览 40人参与
# 从哪些方向判断这个offer值不值得去? #
6482次浏览 91人参与
# 同bg的你秋招战况如何? #
158802次浏览 927人参与
# 度小满求职进展汇总 #
10039次浏览 49人参与
# 实习必须要去大厂吗? #
146581次浏览 1541人参与
# 校招泡的最久的公司是哪家? #
4431次浏览 20人参与
# 你有哪些缓解焦虑的方法? #
37172次浏览 835人参与
# 面试紧张时你会有什么表现? #
1682次浏览 20人参与
# 你喜欢工作还是上学 #
77564次浏览 860人参与
# 入职第一天,你准备什么时候下班 #
85462次浏览 467人参与
# 秋招想进国企该如何准备 #
97702次浏览 487人参与
# 简历无回复,你会继续海投还是优化再投? #
103572次浏览 819人参与
# 机械人的工作环境真的很差吗 #
24991次浏览 119人参与
# 独居后,你的生活是更好了还是更差了? #
28125次浏览 263人参与
牛客网
牛客网在线编程
牛客网题解
牛客企业服务