基本数据结构练习

来源:互联网 发布:廖雪峰java视频百度云 编辑:程序博客网 时间:2024/05/16 12:35

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

题面的话 要求操作如下

操作一
操作二

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

#include<iostream>#include<cstdio>#include<cstdlib>#include<algorithm>#include<cstring>#define maxn 150000#define ls x<<1#define rs x<<1|1using 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