1 条题解

  • 1
    @ 2020-11-30 10:41:44
    #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();
    }
    
  • 1

信息

ID
1003
难度
9
分类
(无)
标签
递交数
1
已通过
1
通过率
100%
上传者