题解

5 条题解

  • 2
    @ 2018-10-14 18:48:15
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<vector>
    #include<algorithm> 
    #define N 300009
    #define M 600009
    using namespace std;
    int en,n,m;
    int w[N],spn[M],bucket[N+M],ans[N];
    vector<int> v1[M],v2[M],v3[M];
    struct nod{
        int u,v,dis,lca;
    }p[N];
    struct edge{
        int e;
        edge *next;
    }*v[N],ed[M];
    inline void add_edge(int s,int e){
        en++;
        ed[en].next = v[s],v[s] = ed+en,v[s]->e =e;
    }
    int read(){
        int x = 0;
        char ch = getchar();
        while(ch < '0' || ch > '9')ch = getchar();
        while(ch >= '0' && ch <= '9'){
            x = x * 10 + ch - '0';
            ch = getchar();
        }
        return x;
    }
    int deep[N],f[N][25],dist[N];
    bool use[N];
    void dfs(int now,int dep){
        use[now] = true;
        deep[now] = dep;
        for(int k = 1;k <= 22; k++){
            int j = f[now][k-1];
            f[now][k] = f[j][k-1];
        }
        for(edge *e = v[now];e;e=e->next)
          if(!use[e->e]){
               f[e->e][0] = now;
               dist[e->e] = dist[now]+1;
               dfs(e->e,dep+1);
          }
        use[now] = false;
    }
    inline int jump(int u,int step){
        for(int k = 0; k <= 22; k++)
          if((step & (1<<k)))u = f[u][k];
        return u;
    }
    inline int qlca(int u,int v){
        if(deep[u] < deep[v])swap(u,v);
        u = jump(u,deep[u]-deep[v]);
        for(int k = 22; k >= 0; k--)
          if(f[u][k] != f[v][k])u = f[u][k],v = f[v][k];
        return u == v ? u : f[u][0];
    }
    void LCA(){                        //关于LCA的组件
        f[1][0] = 1;
        dfs(1,0);
    }
    inline void dfs1(int now){
        use[now] = true;
        int prev = bucket[deep[now]+w[now]+N];
        for(edge *e = v[now];e;e=e->next)
            if(!use[e->e])dfs1(e->e);
        bucket[deep[now]+N] += spn[now];
        ans[now] += bucket[deep[now]+w[now]+N]-prev;
        int len = v1[now].size();
        for(int k = 0; k < len;k++)
          --bucket[deep[v1[now][k]]+N];
        use[now] = false;
    }
    inline void dfs2(int now){
        use[now] = true;
        int prev = bucket[w[now]-deep[now]+N];
        for(edge *e = v[now];e;e=e->next)
          if(!use[e->e])dfs2(e->e);
        int len = v2[now].size();
        for(int k = 0; k < len; k++)
           ++bucket[v2[now][k]+N];
        ans[now] += bucket[w[now]-deep[now]+N] - prev;
        len = v3[now].size();
        for(int k = 0; k < len; k++)
           --bucket[v3[now][k]+N];
        use[now] = false;
    }
    int main(){
        n = read(),m = read();
        for(int i = 1; i <= n-1; i++){
            int u = read(), v = read();
            add_edge(u,v);
            add_edge(v,u);
        }
        for(int i = 1; i <= n; i++)w[i] = read();
        LCA();                    
        for(int i = 1; i <= m; i++){                //预处理 
            int u = read(),v = read();
            p[i].u = u;
            p[i].v = v;
            p[i].lca = qlca(u,v);
            p[i].dis = dist[u]+dist[v]-dist[p[i].lca]*2;
            spn[u]++;
            v1[p[i].lca].push_back(u);
            v2[v].push_back(p[i].dis-deep[p[i].v]);
            v3[p[i].lca].push_back(p[i].dis-deep[p[i].v]);
        }
        dfs1(1);        //从下至上
        dfs2(1);        //从上至下
        for(int i = 1; i <= m; i++)
           if(deep[p[i].u] == deep[p[i].lca]+w[p[i].lca]) ans[p[i].lca]--;
        for(int i = 1; i <= n; i++)
          printf("%d ",ans[i]);
        printf("\n");
        return 0;
    }
    
  • 0
    @ 2020-11-25 14:55:34

    第一個是實現算法的程序(會超時最後一個測試點),第二個是優化後的程序(AC)

    #include <cmath>
    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <algorithm>
    #include <vector>
    #include <deque>
    using namespace std;
    
    namespace dts
    {
        typedef unsigned int uint;
        const uint lgs=19;
        int cnt,maxdep;
        class tr_node
        {
            public:
                int fa,dep=0,size,hs,top,id=0;
                vector<int> s;
        };
        int rk[(1<<lgs)+1],inrec[(1<<lgs)+1],outrec[(1<<lgs)+1];
        tr_node tr[(1<<lgs)+1];
        void tr_dfs1(int now,int fa)
        {
            tr[now].fa=fa;
            if (now>0)
                tr[now].dep=tr[fa].dep+1;
            maxdep=max(maxdep,tr[now].dep);
            tr[now].size=1;
            tr[now].hs=-1;
            for (int i=0;i<tr[now].s.size();i++)
                if (tr[now].s[i]!=fa)
                {
                    int next=tr[now].s[i];
                    tr_dfs1(next,now);
                    tr[now].size+=tr[next].size;
                    if (tr[now].hs==-1)
                        tr[now].hs=next;
                    else if (tr[tr[now].hs].size<tr[next].size)
                        tr[now].hs=next;
                }
        }
        void tr_dfs2(int now,int top)
        {
            tr[now].top=top;
            tr[now].id=++cnt;
            inrec[now]=cnt;
            rk[cnt]=now;
            if (tr[now].hs!=-1)
            {
                tr_dfs2(tr[now].hs,top);
                for (int i=0;i<tr[now].s.size();i++)
                    if (tr[now].s[i]!=tr[now].fa&&tr[now].s[i]!=tr[now].hs)
                        tr_dfs2(tr[now].s[i],tr[now].s[i]);
            }
            outrec[now]=cnt;
        }
        void tr_build(int rt)
        {
            cnt=0,maxdep=0;
            tr_dfs1(rt,0);
            tr_dfs2(rt,rt);
        }
        int lca(int x,int y)
        {
            while (tr[x].top!=tr[y].top)
            {
                if (tr[tr[x].top].dep<tr[tr[y].top].dep)
                    swap(x,y);
                x=tr[tr[x].top].fa;
            }
            if (tr[x].dep<tr[y].dep)
                return x;
            else
                return y;
        }
        class segtree
        {
            public:
                int size=0;
                class strec
                {
                    public:
                        int rt=-1,rtl=1,rtr=-1;
                };
                vector<strec> rec;
                deque<int> fa,lc,rc,sl,sr,smid,sum,sumlz;
                void reszcl(int rec_size)
                {
                    size=0;
                    rec.resize(rec_size);
                    fa.clear(),lc.clear(),rc.clear();
                    sl.clear(),sr.clear(),smid.clear();
                    sum.clear(),sumlz.clear();
                }
                void set_st(int rcp,int l,int r)
                {
                    rec[rcp].rt=-1,rec[rcp].rtl=l,rec[rcp].rtr=r;
                }
                int len(int now)
                {
                    return sr[now]-sl[now]+1;
                }
                void update(int rcp,int &now,int fath,int l,int r,int val)
                {
                    if (now==-1||now+1>size)
                    {
                        now=size++;
                        fa.push_back(fath),lc.push_back(-1),rc.push_back(-1);
                        sum.push_back(0),sumlz.push_back(0);
                        if (now==rec[rcp].rt)
                            sl.push_back(rec[rcp].rtl),sr.push_back(rec[rcp].rtr);
                        else
                        {
                            if (lc[fa[now]]==now)
                                sl.push_back(sl[fa[now]]),sr.push_back(smid[fa[now]]);
                            else if (rc[fa[now]]==now)
                                sl.push_back(smid[fa[now]]+1),sr.push_back(sr[fa[now]]);
                        }
                        smid.push_back((sl[now]+sr[now])>>1);
                    }
                    if (sl[now]==l&&r==sr[now])
                    {
                        sum[now]+=len(now)*val;
                        sumlz[now]+=val;
                    }
                    else
                    {
                        if (sumlz[now]!=0)
                        {
                            update(rcp,lc[now],now,sl[now],smid[now],sumlz[now]);
                            update(rcp,rc[now],now,smid[now]+1,sr[now],sumlz[now]);
                            sumlz[now]=0;
                        }
                        if (r<=smid[now])
                            update(rcp,lc[now],now,l,r,val);
                        else if (smid[now]+1<=l)
                            update(rcp,rc[now],now,l,r,val);
                        else
                            update(rcp,lc[now],now,l,smid[now],val),update(rcp,rc[now],now,smid[now]+1,r,val);
                        sum[now]=((lc[now]==-1)?0:sum[lc[now]])+((rc[now]==-1)?0:sum[rc[now]]);
                    }
                }
                int ask(int rcp,int now,int l,int r)
                {
                    if (now==-1||now+1>size)
                        return 0;
                    if (sl[now]==l&&r==sr[now])
                        return sum[now];
                    else
                    {
                        if (sumlz[now]!=0)
                        {
                            update(rcp,lc[now],now,sl[now],smid[now],sumlz[now]);
                            update(rcp,rc[now],now,smid[now]+1,sr[now],sumlz[now]);
                            sumlz[now]=0;
                        }
                        if (r<=smid[now])
                            return ask(rcp,lc[now],l,r);
                        else if (smid[now]+1<=l)
                            return ask(rcp,rc[now],l,r);
                        else
                            return ask(rcp,lc[now],l,smid[now])+ask(rcp,rc[now],smid[now]+1,r);
                    }
                }
        };
        segtree udst;
        
        int n,m,w[(1<<lgs)+1],s[(1<<lgs)+1],t[(1<<lgs)+1],ans[(1<<lgs)+1];
        
        void main()
        {
            scanf("%d%d",&n,&m);
            for (int i=0;i<=n;i++)
                tr[i].s.clear();
            tr[0].s.push_back(1);
            for (int i=1;i<n;i++)
            {
                int x,y;
                scanf("%d%d",&x,&y);
                tr[x].s.push_back(y);
                tr[y].s.push_back(x);
            }
            for (int i=1;i<=n;i++)
                scanf("%d",&w[i]);
            tr_build(1);
            for (int i=1;i<=m;i++)
                scanf("%d%d",&s[i],&t[i]);
            memset(ans,0,sizeof(ans));
            udst.reszcl(n<<1|1);
            for (int i=0;i<=(n<<1);i++)
                udst.set_st(i,1,n);
            for (int i=1;i<=m;i++)
            {
                int lcan=lca(s[i],t[i]),nums=tr[s[i]].dep;
                if (tr[s[i]].id>0)
                    udst.update(nums,udst.rec[nums].rt,-1,tr[s[i]].id,tr[s[i]].id,1);
                if (tr[tr[lcan].fa].id>0)
                    udst.update(nums,udst.rec[nums].rt,-1,tr[tr[lcan].fa].id,tr[tr[lcan].fa].id,-1);
            }
            for (int i=1;i<=n;i++)
            {
                int nums=tr[i].dep+w[i];
                ans[i]+=udst.ask(nums,udst.rec[nums].rt,inrec[i],outrec[i]);
            }
            udst.reszcl(n<<1|1);
            for (int i=0;i<=(n<<1);i++)
                udst.set_st(i,1,n);
            for (int i=1;i<=m;i++)
            {
                int lcan=lca(s[i],t[i]),numt=tr[s[i]].dep-(tr[lcan].dep<<1)+n;
                if (tr[t[i]].id>0)
                    udst.update(numt,udst.rec[numt].rt,-1,tr[t[i]].id,tr[t[i]].id,1);
                if (tr[lcan].id>0)
                    udst.update(numt,udst.rec[numt].rt,-1,tr[lcan].id,tr[lcan].id,-1);
            }
            for (int i=1;i<=n;i++)
            {
                int numt=w[i]-tr[i].dep+n;
                ans[i]+=udst.ask(numt,udst.rec[numt].rt,inrec[i],outrec[i]);
            }
            for (int i=1;i<=n;i++)
                printf("%d ",ans[i]);
        }
    }
    
    int main()
    {
        dts::main();
    }
    

    分割線

    #include <cmath>
    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <algorithm>
    #include <vector>
    #include <deque>
    using namespace std;
    
    namespace dts
    {
        typedef unsigned int uint;
        const uint lgs=19;
        int cnt,maxdep;
        class tr_node
        {
            public:
                int fa,dep=0,size,hs,top,id=0;
                vector<int> s;
        };
        int rk[(1<<lgs)+1],inrec[(1<<lgs)+1],outrec[(1<<lgs)+1];
        tr_node tr[(1<<lgs)+1];
        void tr_dfs1(int now,int fa)
        {
            tr[now].fa=fa;
            if (now>0)
                tr[now].dep=tr[fa].dep+1;
            maxdep=max(maxdep,tr[now].dep);
            tr[now].size=1;
            tr[now].hs=-1;
            for (int i=0;i<tr[now].s.size();i++)
                if (tr[now].s[i]!=fa)
                {
                    int next=tr[now].s[i];
                    tr_dfs1(next,now);
                    tr[now].size+=tr[next].size;
                    if (tr[now].hs==-1)
                        tr[now].hs=next;
                    else if (tr[tr[now].hs].size<tr[next].size)
                        tr[now].hs=next;
                }
        }
        void tr_dfs2(int now,int top)
        {
            tr[now].top=top;
            tr[now].id=++cnt;
            inrec[now]=cnt;
            rk[cnt]=now;
            if (tr[now].hs!=-1)
            {
                tr_dfs2(tr[now].hs,top);
                for (int i=0;i<tr[now].s.size();i++)
                    if (tr[now].s[i]!=tr[now].fa&&tr[now].s[i]!=tr[now].hs)
                        tr_dfs2(tr[now].s[i],tr[now].s[i]);
            }
            outrec[now]=cnt;
        }
        void tr_build(int rt)
        {
            cnt=0,maxdep=0;
            tr_dfs1(rt,0);
            tr_dfs2(rt,rt);
        }
        int lca(int x,int y)
        {
            while (tr[x].top!=tr[y].top)
            {
                if (tr[tr[x].top].dep<tr[tr[y].top].dep)
                    swap(x,y);
                x=tr[tr[x].top].fa;
            }
            if (tr[x].dep<tr[y].dep)
                return x;
            else
                return y;
        }
        class segtree
        {
            public:
                int size=0;
                class strec
                {
                    public:
                        int rt=-1,rtl=1,rtr=-1;
                };
                vector<strec> rec;
                vector<int> fa,lc,rc,sl,sr,smid,sum,sumlz;
                //deque<int> fa,lc,rc,sl,sr,smid,sum,sumlz;
                void reszcl(int rec_size)
                {
                    size=0;
                    rec.resize(rec_size);
                    /*fa.clear(),lc.clear(),rc.clear();
                    sl.clear(),sr.clear(),smid.clear();
                    sum.clear(),sumlz.clear();*/
                    fa.resize(rec_size<<3),lc.resize(rec_size<<3),rc.resize(rec_size<<3);
                    sl.resize(rec_size<<3),sr.resize(rec_size<<3),smid.resize(rec_size<<3);
                    sum.resize(rec_size<<3),sumlz.resize(rec_size<<3);
                }
                void set_st(int rcp,int l,int r)
                {
                    rec[rcp].rt=-1,rec[rcp].rtl=l,rec[rcp].rtr=r;
                }
                int len(int now)
                {
                    return sr[now]-sl[now]+1;
                }
                /*
                void update(int rcp,int &now,int fath,int l,int r,int val)
                {
                    if (now==-1||now+1>size)
                    {
                        now=size++;
                        fa.push_back(fath),lc.push_back(-1),rc.push_back(-1);
                        sum.push_back(0),sumlz.push_back(0);
                        if (now==rec[rcp].rt)
                            sl.push_back(rec[rcp].rtl),sr.push_back(rec[rcp].rtr);
                        else
                        {
                            if (lc[fa[now]]==now)
                                sl.push_back(sl[fa[now]]),sr.push_back(smid[fa[now]]);
                            else if (rc[fa[now]]==now)
                                sl.push_back(smid[fa[now]]+1),sr.push_back(sr[fa[now]]);
                        }
                        smid.push_back((sl[now]+sr[now])>>1);
                    }
                    if (sl[now]==l&&r==sr[now])
                    {
                        sum[now]+=len(now)*val;
                        sumlz[now]+=val;
                    }
                    else
                    {
                        if (sumlz[now]!=0)
                        {
                            update(rcp,lc[now],now,sl[now],smid[now],sumlz[now]);
                            update(rcp,rc[now],now,smid[now]+1,sr[now],sumlz[now]);
                            sumlz[now]=0;
                        }
                        if (r<=smid[now])
                            update(rcp,lc[now],now,l,r,val);
                        else if (smid[now]+1<=l)
                            update(rcp,rc[now],now,l,r,val);
                        else
                            update(rcp,lc[now],now,l,smid[now],val),update(rcp,rc[now],now,smid[now]+1,r,val);
                        sum[now]=((lc[now]==-1)?0:sum[lc[now]])+((rc[now]==-1)?0:sum[rc[now]]);
                    }
                }
                */
                void update(int rcp,int now,int *pnow,int fath,int l,int r,int val)
                {
                    if (now==-1||now+1>size)
                    {
                        now=size++,*pnow=now;
                        if (size>fa.size())
                        {
                            fa.resize(size,-1),lc.resize(size,-1),rc.resize(size,-1);
                            sl.resize(size,1),sr.resize(size,-1),smid.resize(size,0);
                            sum.resize(size,0),sumlz.resize(size,0);
                        }
                        fa[now]=fath,lc[now]=rc[now]=-1;
                        sum[now]=sumlz[now]=0;
                        if (now==rec[rcp].rt)
                            sl[now]=rec[rcp].rtl,sr[now]=rec[rcp].rtr;
                        else
                        {
                            if (lc[fa[now]]==now)
                                sl[now]=sl[fa[now]],sr[now]=smid[fa[now]];
                            else if (rc[fa[now]]==now)
                                sl[now]=smid[fa[now]]+1,sr[now]=sr[fa[now]];
                        }
                        smid[now]=(sl[now]+sr[now])>>1;
                    }
                    if (sl[now]==l&&r==sr[now])
                    {
                        sum[now]+=len(now)*val;
                        sumlz[now]+=val;
                    }
                    else
                    {
                        if (sumlz[now]!=0)
                        {
                            update(rcp,lc[now],&lc[now],now,sl[now],smid[now],sumlz[now]);
                            update(rcp,rc[now],&rc[now],now,smid[now]+1,sr[now],sumlz[now]);
                            sumlz[now]=0;
                        }
                        if (r<=smid[now])
                            update(rcp,lc[now],&lc[now],now,l,r,val);
                        else if (smid[now]+1<=l)
                            update(rcp,rc[now],&rc[now],now,l,r,val);
                        else
                            update(rcp,lc[now],&lc[now],now,l,smid[now],val),update(rcp,rc[now],&rc[now],now,smid[now]+1,r,val);
                        sum[now]=((lc[now]==-1)?0:sum[lc[now]])+((rc[now]==-1)?0:sum[rc[now]]);
                    }
                }
                int ask(int rcp,int now,int l,int r)
                {
                    if (now==-1||now+1>size)
                        return 0;
                    if (sl[now]==l&&r==sr[now])
                        return sum[now];
                    else
                    {
                        if (sumlz[now]!=0)
                        {
                            update(rcp,lc[now],&lc[now],now,sl[now],smid[now],sumlz[now]);
                            update(rcp,rc[now],&rc[now],now,smid[now]+1,sr[now],sumlz[now]);
                            sumlz[now]=0;
                        }
                        if (r<=smid[now])
                            return ask(rcp,lc[now],l,r);
                        else if (smid[now]+1<=l)
                            return ask(rcp,rc[now],l,r);
                        else
                            return ask(rcp,lc[now],l,smid[now])+ask(rcp,rc[now],smid[now]+1,r);
                    }
                }
        };
        segtree udst;
        
        int n,m,w[(1<<lgs)+1],s[(1<<lgs)+1],t[(1<<lgs)+1],ans[(1<<lgs)+1];
        
        /*
        void main()
        {
            scanf("%d%d",&n,&m);
            for (int i=0;i<=n;i++)
                tr[i].s.clear();
            tr[0].s.push_back(1);
            for (int i=1;i<n;i++)
            {
                int x,y;
                scanf("%d%d",&x,&y);
                tr[x].s.push_back(y);
                tr[y].s.push_back(x);
            }
            for (int i=1;i<=n;i++)
                scanf("%d",&w[i]);
            tr_build(1);
            for (int i=1;i<=m;i++)
                scanf("%d%d",&s[i],&t[i]);
            memset(ans,0,sizeof(ans));
            udst.reszcl(n<<1|1);
            for (int i=0;i<=(n<<1);i++)
                udst.set_st(i,1,n);
            for (int i=1;i<=m;i++)
            {
                int lcan=lca(s[i],t[i]),nums=tr[s[i]].dep;
                if (tr[s[i]].id>0)
                    udst.update(nums,udst.rec[nums].rt,-1,tr[s[i]].id,tr[s[i]].id,1);
                if (tr[tr[lcan].fa].id>0)
                    udst.update(nums,udst.rec[nums].rt,-1,tr[tr[lcan].fa].id,tr[tr[lcan].fa].id,-1);
            }
            for (int i=1;i<=n;i++)
            {
                int nums=tr[i].dep+w[i];
                ans[i]+=udst.ask(nums,udst.rec[nums].rt,inrec[i],outrec[i]);
            }
            udst.reszcl(n<<1|1);
            for (int i=0;i<=(n<<1);i++)
                udst.set_st(i,1,n);
            for (int i=1;i<=m;i++)
            {
                int lcan=lca(s[i],t[i]),numt=tr[s[i]].dep-(tr[lcan].dep<<1)+n;
                if (tr[t[i]].id>0)
                    udst.update(numt,udst.rec[numt].rt,-1,tr[t[i]].id,tr[t[i]].id,1);
                if (tr[lcan].id>0)
                    udst.update(numt,udst.rec[numt].rt,-1,tr[lcan].id,tr[lcan].id,-1);
            }
            for (int i=1;i<=n;i++)
            {
                int numt=w[i]-tr[i].dep+n;
                ans[i]+=udst.ask(numt,udst.rec[numt].rt,inrec[i],outrec[i]);
            }
            for (int i=1;i<=n;i++)
                printf("%d ",ans[i]);
        }
        */
        void main()
        {
            scanf("%d%d",&n,&m);
            for (int i=0;i<=n;i++)
                tr[i].s.clear();
            tr[0].s.push_back(1);
            for (int i=1;i<n;i++)
            {
                int x,y;
                scanf("%d%d",&x,&y);
                tr[x].s.push_back(y);
                tr[y].s.push_back(x);
            }
            for (int i=1;i<=n;i++)
                scanf("%d",&w[i]);
            tr_build(1);
            for (int i=1;i<=m;i++)
                scanf("%d%d",&s[i],&t[i]);
            memset(ans,0,sizeof(ans));
            udst.reszcl(n<<1|1);
            for (int i=0;i<=(n<<1);i++)
                udst.set_st(i,1,n);
            for (int i=1;i<=m;i++)
            {
                int lcan=lca(s[i],t[i]),nums=tr[s[i]].dep;
                if (tr[s[i]].id>0)
                    udst.update(nums,udst.rec[nums].rt,&udst.rec[nums].rt,-1,tr[s[i]].id,tr[s[i]].id,1);
                if (tr[tr[lcan].fa].id>0)
                    udst.update(nums,udst.rec[nums].rt,&udst.rec[nums].rt,-1,tr[tr[lcan].fa].id,tr[tr[lcan].fa].id,-1);
            }
            for (int i=1;i<=n;i++)
            {
                int nums=tr[i].dep+w[i];
                ans[i]+=udst.ask(nums,udst.rec[nums].rt,inrec[i],outrec[i]);
            }
            udst.reszcl(n<<1|1);
            for (int i=0;i<=(n<<1);i++)
                udst.set_st(i,1,n);
            for (int i=1;i<=m;i++)
            {
                int lcan=lca(s[i],t[i]),numt=tr[s[i]].dep-(tr[lcan].dep<<1)+n;
                if (tr[t[i]].id>0)
                    udst.update(numt,udst.rec[numt].rt,&udst.rec[numt].rt,-1,tr[t[i]].id,tr[t[i]].id,1);
                if (tr[lcan].id>0)
                    udst.update(numt,udst.rec[numt].rt,&udst.rec[numt].rt,-1,tr[lcan].id,tr[lcan].id,-1);
            }
            for (int i=1;i<=n;i++)
            {
                int numt=w[i]-tr[i].dep+n;
                ans[i]+=udst.ask(numt,udst.rec[numt].rt,inrec[i],outrec[i]);
            }
            for (int i=1;i<=n;i++)
                printf("%d ",ans[i]);
        }
    }
    
    int main()
    {
        dts::main();
    }
    
  • -1
    @ 2018-10-07 08:19:50
  • -25
    @ 2017-03-04 10:03:00

    䐞䐞的六十分,但好想好做
    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<queue>
    #include<stack>
    #include<cmath>
    using namespace std;
    int n,m;
    int point[100001],nex[100001],to[100001],father[100001],deep[100001];
    //父节点只想的第一条边 此边的下一条边 边的指向 父节点 深度
    int belong[100001],watch[100001];//属于集合 观察时间
    int start;//根节点
    int s[100001],t[100001],lca[100001];//每一对询问的起始点及其最近公共祖先
    bool whether_father[100001],hasover[100001];//是否是父亲 此次询问是否已结束
    int ans[100001];//答案
    int set(int k)//求并查集的指向
    {
    if(belong[k]!=k)belong[k]=set(father[k]);
    return belong[k];
    }
    int outline_targan(int p)//求LCA
    {
    deep[p]=deep[father[p]]+1;//记录深度
    int side=point[p];
    while(side!=0)//访问本点的所有子节点
    {
    outline_targan(to[side]);
    side=nex[side];
    }
    for(int i=1;i<=m;i++)//寻求此对询问是否属于同一集合
    {
    if((hasover[i]==false)&&(set(s[i])==set(t[i])))//询问属于同一集合且未完成询问
    {

    lca[i]=set(t[i]);
    hasover[i]=true;//标记此次询问已经被完成
    }
    }
    belong[p]=father[p];//本点结束访问后,将自己指向父亲
    return 0;
    }
    int main()
    {
    //freopen("天天爱跑步测试数据1.txt","r",stdin);
    memset(hasover,false,sizeof(hasover));//所有询问尚未完成
    memset(lca,0,sizeof(lca));
    memset(watch,0,sizeof(watch));
    memset(whether_father,true,sizeof(whether_father));
    memset(point,0,sizeof(point));
    memset(to,0,sizeof(to));
    memset(father,0,sizeof(father));
    memset(ans,0,sizeof(ans));
    memset(s,0,sizeof(s));
    memset(t,0,sizeof(t));
    memset(deep,0,sizeof(deep));//每个节点的深度
    memset(nex,0,sizeof(nex));//以上初始化
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++)belong[i]=i;//并查集初始化
    for(int i=1;i<=n-1;i++)//输入树
    {
    int u,v;
    scanf("%d%d",&u,&v);
    nex[i]=point[u];
    point[u]=i;
    father[v]=u;
    to[i]=v;
    whether_father[v]=false;
    }
    start=1;
    while(whether_father[start]!=true)start++;//确定根节点
    for(int i=1;i<=n;i++)//输入观察时间
    scanf("%d",&watch[i]);
    for(int i=1;i<=m;i++)//输入每一组询问的起始点
    scanf("%d%d",&s[i],&t[i]);

    father[start]=start;
    outline_targan(start);//离线targan求最近公共祖先

    for(int i=1;i<=m;i++)//处理每一组询问
    {
    int p=s[i],q=t[i];
    if(deep[s[i]]>deep[lca[i]])
    {
    do
    {
    if(deep[s[i]]-deep[p]==watch[p])ans[p]++;
    p=father[p];
    }while(p!=lca[i]);//从起始点向上追溯
    }
    if(deep[lca[i]]-deep[s[i]]==watch[lca[i]])ans[lca[i]]++;//lca单独来 考虑
    if(deep[t[i]]>deep[lca[i]])
    {
    do
    {
    if(deep[s[i]]+deep[q]-2*deep[lca[i]]==watch[q])ans[q]++;
    q=father[q];
    }while(q!=lca[i]);//从终点向上追溯
    }
    }
    for(int l=1;l<=n;l++)printf("%d ",ans[l]);
    return 0;
    }

    • @ 2017-07-06 11:15:18

      你这个只有25分吧。

  • 1

信息

ID
2004
难度
8
分类
(无)
标签
递交数
1681
已通过
154
通过率
9%
被复制
16
上传者