基本数据结构练习

大概对dalao们而言的确是基本了
可是我只觉得这简直 基(变)本(态)

题面的话 要求操作如下

操作一
操作二

然后据说dalao们都在打主席树然而垃圾并不懂那是什么
上次打树剖题也有蛮久了忘得差不多了qwq
还好有强行不超纲的出题人救我等渣渣于水深火热之中

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<cstring>
#define maxn 150000
#define ls x<<1
#define rs x<<1|1
using namespace std;
int head[maxn],to[maxn],nxt[maxn],tot;
int tree[maxn*4],sz[maxn],tp[maxn],son[maxn];
int fa[maxn],ed[maxn],dfn[maxn];
int de[maxn],df=0,n,ans[maxn],m1,m;
struct hh {
    int id,x,y,z,t;
} g[maxn];
void link(int x,int y) {
    nxt[++tot]=head[x];
    to[tot]=y;
    head[x]=tot;
}
void update(int x,int l,int r,int xx,int v) {
    if (l==r) {
        tree[x]=v;
        return ;
    }
    int mid=(l+r)>>1;
    if (xx<=mid) update(ls,l,mid,xx,v);
    else  update(rs,mid+1,r,xx,v);
    tree[x]=tree[ls]+tree[rs];
}
int query(int x,int l,int r,int ll,int rr) {
    if (ll<=l&&r<=rr) return tree[x];
    int mid=(l+r)>>1;
    int ans=0;
    if (ll<=mid) ans+=query(ls,l,mid,ll,rr);
    if (rr>mid) ans+=query(rs,mid+1,r,ll,rr);
    return ans;
}
void dfs(int x) {
    sz[x]++;
    for (int i=head[x]; i; i=nxt[i]) {
        int t=to[i];
        if (t==fa[x])continue;
        fa[t]=x;
        de[t]=de[x]+1;
        dfs(t);
        sz[x]+=sz[t];
        if (sz[t]>sz[son[x]]) son[x]=t;
    }
}
void dfs2(int x,int top) {
    tp[x]=top;
    dfn[x]=++df;
    if (son[x]) dfs2(son[x],top);
    for (int i=head[x]; i; i=nxt[i]) {
        int t=to[i];
        if (t==fa[x]||t==son[x])continue;
        dfs2(t,t);
    }
    ed[x]=df;
}
int doit(int x,int y) {
    int ans=0;
    while (tp[x]!=tp[y]) {
        if (de[tp[x]]<de[tp[y]]) swap(x,y);
        ans+=query(1,1,n,dfn[tp[x]],dfn[x]);
        x=fa[tp[x]];
    }
    if (de[x]>de[y]) swap(x,y);
    ans+=query(1,1,n,dfn[x],dfn[y]);
    return ans;
}
bool comp(hh a,hh b) {
    if (a.z!=b.z) return a.z<b.z;
    else return a.id<b.id;
}
int main() {
    scanf ("%d",&n);
    for (int i=1; i<n; ++i) {
        int x,y;
        scanf ("%d%d",&x,&y);
        link(x,y);
        link(y,x);
    }
    de[1]=1,dfs(1),dfs2(1,1);
    scanf ("%d",&m1);
    for (int i=1; i<=m1; ++i) {
        int x;
        scanf ("%d",&x);
        int y,z;
        if (x==1) {
            scanf ("%d%d",&y,&z);
            update(1,1,n,dfn[y],z);
        }
        if (x==2) {
            scanf ("%d%d",&y,&z);
            cout<<doit(y,z)<<endl;
        }
        if (x==3) {
            scanf ("%d",&y);
            cout<<query(1,1,n,dfn[y],ed[y])<<endl;
        }
    }
    scanf ("%d",&m);
    for (int i=1; i<=m; ++i) {
        int x;
        scanf ("%d",&x);
        g[i].id=x,g[i].t=i;
        if (x==1) {
            scanf("%d%d%d",&g[i].x,&g[i].y,&g[i].z);
        }
        if (x==2) {
            scanf ("%d%d",&g[i].x,&g[i].z);
        }
    }
    for (int i=1; i<=n; ++i)
    g[++m].id=0,g[m].x=dfn[i],g[m].z=query(1,1,n,dfn[i],dfn[i]);
    sort(g+1,g+m+1,comp);
    memset(tree,0,sizeof(tree));
    for (int i=1; i<=m; ++i) {
        if (g[i].id==0) update(1,1,n,g[i].x,1);
        if (g[i].id==1) ans[g[i].t]=doit(g[i].x,g[i].y);
        else ans[g[i].t]=query(1,1,n,dfn[g[i].x],ed[g[i].x]);
    }
    for (int i=1; i<=m-n; ++i) cout<<ans[i]<<endl;
    return 0;
}

考场上前30分都没拿到实在是比较可惜
打到了doit里面就开始懵逼 不记得dfn在哪里求的来着了
老了老了脑子也不怎么好使了qwq
另外第二问的处理方式简直太dio了!不由得惊叹= =
声明一下 我代码也是学的标程啊!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值