天天爱跑步

题面

lca+树上差分

#include<vector>
#include<cstdio>
#include<algorithm>
#define rg register
#define ci const int
#define cl const long long int

typedef long long int ll;

namespace IO {
    char buf[90];
}

template<typename T>
inline void qr(T &x) {
    char ch=getchar(),lst=' ';
    while(ch>'9'||ch<'0') lst=ch,ch=getchar();
    while(ch>='0'&&ch<='9') x=(x<<1)+(x<<3)+(ch^48),ch=getchar();
    if(lst=='-') x=-x;
}

template<typename T>
inline void write(T x,const char aft,const bool pt) {
    if(x<0) x=-x,putchar('-');
    int top=0;
    do {
        IO::buf[++top]=x%10+'0';
        x/=10;
    } while(x);
    while(top) putchar(IO::buf[top--]);
    if(pt) putchar(aft);
}

template<typename T>
inline T mmax(const T a,const T b) {if(a>b) return a;return b;}
template<typename T>
inline T mmin(const T a,const T b) {if(a<b) return a;return b;}
template<typename T>
inline T mabs(const T a) {if(a<0) return -a;return a;}

template<typename T>
inline void mswap(T &a,T &b) {
    T temp=a;a=b;b=temp;
}

const int maxn = 1000010;
const int maxm = 1000010;
const int ZAY = 300004;

struct Edge {
    int to,nxt;
};
Edge edge[maxm];int hd[maxn],ecnt;
inline void cont(ci from,ci to) {
    Edge &e=edge[++ecnt];
    e.to=to;e.nxt=hd[from];hd[from]=ecnt;
}

struct M {
    int s,t,an,sum,tk;
    inline bool operator<(const M &_others) const {
        return this->sum < _others.sum;
    }
};
M MU[maxn];

struct W {
    int v,num,ans;
    inline bool operator<(const W &_others) const {
        return this->v < _others.v;
    }
};
W w[maxn];

struct C {
    int ud,v,tp;
    C (int _ud=0,int _v=0,int _tp=0) {ud=_ud,v=_v,tp=_tp;}
};
std::vector<C>cg[maxn];

int n,m;
int deepth[maxn],fa[maxn],LCA[30][maxn],pos[maxn],lft[maxn],rt[maxn];

void t1();
void s1();
void lian();
void baoli();
void zhengjie();
void dfs(ci,ci);
int ask(int,int);
int dfsearch(ci,ci);
void deepfs(ci,ci);
void dfirsts(ci,ci);

inline bool cmp(const W &_a,const W & _b) {
    return _a.num < _b.num;
}

int main() {
    qr(n);qr(m);
    rg int a,b;
    for(rg int i=1;i<n;++i) {
        a=b=0;qr(a);qr(b);
        cont(a,b);cont(b,a);
    }
    for(rg int i=1;i<=n;++i) {
        qr(w[i].v);w[i].num=i;
    }
    for(rg int i=1;i<=m;++i) {
        qr(MU[i].s);qr(MU[i].t);
    }
    int _num=n%10;
    if(_num < 4) baoli();
    else if(_num == 4) lian();
    else if(_num == 5) s1();
    else if(_num == 6) t1();
    else zhengjie();
    return 0;
}

void dfs(ci u,ci fat) {
    deepth[u]=deepth[fa[u]=fat]+1;
    LCA[0][u]=fat;
    for(rg int i=0;LCA[i][u];++i) {
        LCA[i+1][u]=LCA[i][LCA[i][u]];
    }
    for(rg int i=hd[u];i;i=edge[i].nxt) if(edge[i].to != fat)
        dfs(edge[i].to,u);
}

int ask(int x,int y) {
    if(deepth[x] < deepth[y]) mswap(x,y);
    rg int delta=deepth[x]-deepth[y];
    for(rg int i=25;delta;--i) if(delta & (1<<i)) {
        x=LCA[i][x],delta^=(1<<i);
    }
    if(x == y) return x;
    for(rg int i=25;i != -1;--i) if(LCA[i][x] != LCA[i][y]) {
        x=LCA[i][x],y=LCA[i][y];
    }
    return LCA[0][x];
}

void baoli() {
    dfs(1,0);
    for(rg int i=1;i<=m;++i) {
        MU[i].an=ask(MU[i].s,MU[i].t);
        pos[i]=MU[i].s;
    }
    std::sort(w+1,w+1+n);
    rg int j=1;
    for(rg int i=0;i<n;++i) {
        while(j <= n) {
            if(w[j].v != i) break;
            for(rg int k=1;k<=m;++k) if(pos[k] == w[j].num) ++w[j].ans;
            ++j;
        }
        for(rg int k=1;k<=m;++k) if(deepth[MU[k].s]+deepth[MU[k].t]-2*deepth[MU[k].an] > i) {
            int _d=deepth[MU[k].s]-deepth[MU[k].an];
            if(_d > i) {
                pos[k]=fa[pos[k]];
            }
            else {
                _d=deepth[MU[k].s]-deepth[MU[k].an]+deepth[MU[k].t]-deepth[MU[k].an]-i-1;
                int _t=MU[k].t;
                for(rg int h=25;_d;--h) if(_d & (1<<h)) {
                    _t=LCA[h][_t],_d^=(1<<h);
                }
                pos[k]=_t;
            }
        }
        else pos[k]=0;
    }
    while(j <= n) {
        for(rg int k=1;k<=m;++k) if(pos[k] == w[j].num) ++w[j].ans;
        ++j;
    }
    std::sort(w+1,w+1+n,cmp);
    for(rg int i=1;i<n;++i) write(w[i].ans,' ',true);
    write(w[n].ans,'\n',true);
}

void lian() {
    for(rg int i=1;i<=m;++i) {
        if(MU[i].t >= MU[i].s) ++rt[MU[i].s],MU[i].sum=MU[i].t-MU[i].s;
        else ++lft[MU[i].s],MU[i].sum=MU[i].s-MU[i].t;
    }
    std::sort(MU+1,MU+1+m);
    std::sort(w+1,w+1+n);
    rg int j=0;
    for(rg int i=1;i<=n;++i) {
        while(j <= m) {
            if(MU[j].sum >= w[i].v) break;
            if(MU[j].s <= MU[j].t) --rt[MU[j].s];
            else --lft[MU[j].s];
            ++j;
        }
        int _d=w[i].num-w[i].v;
        if(_d > 0) w[i].ans+=rt[_d];
        _d=w[i].num+w[i].v;
        if(_d <= n) w[i].ans+=lft[_d];
    }
    std::sort(w+1,w+1+n,cmp);
    for(rg int i=1;i<n;++i) write(w[i].ans,' ',true);
    write(w[n].ans,'\n',true);
}

void s1() {
    deepth[0]=-1;
    dfs(1,0);
    for(rg int i=1;i<=m;++i) {
        ++lft[MU[i].t];
    }
    int _cnt=dfsearch(1,0);
    if(!w[1].v) w[1].ans=_cnt;
    for(rg int i=1;i<n;++i) write(w[i].ans,' ',true);
    write(w[n].ans,'\n',true);
}

int dfsearch(ci u,ci fat) {
    rg int _cnt=lft[u];
    for(rg int i=hd[u];i;i=edge[i].nxt) if(edge[i].to != fat) 
        _cnt+=dfsearch(edge[i].to,u);
    if(w[u].v == deepth[u]) w[u].ans=_cnt;
    return _cnt;
}

void deepfs(ci u,ci fat) {
    rg int _c=lft[w[u].v+deepth[u]+ZAY];
    lft[deepth[u]+ZAY]+=rt[u];
    for(rg int i=hd[u];i;i=edge[i].nxt) if(edge[i].to != fat)
        deepfs(edge[i].to,u);
    w[u].ans=lft[w[u].v+deepth[u]+ZAY]-_c;
}

void t1() {
    deepth[0]=-1;
    for(rg int i=1;i<=m;++i) ++rt[MU[i].s];
    dfs(1,0);
    deepfs(1,0);
    for(rg int i=1;i<n;++i) write(w[i].ans,' ',true);
    write(w[n].ans,'\n',true);
}

void zhengjie() {
    dfs(1,0);
    for(rg int i=1;i<=n;++i) {
        MU[i].an=ask(MU[i].s,MU[i].t);
        MU[i].sum=deepth[MU[i].s]-2*deepth[MU[i].an]+deepth[MU[i].t]+1;
        cg[MU[i].s].push_back(C(1,deepth[MU[i].s],1));
        cg[MU[i].t].push_back(C(2,deepth[MU[i].t]-MU[i].sum+1+ZAY,1));
        cg[MU[i].an].push_back(C(1,deepth[MU[i].s],-1));
        cg[fa[MU[i].an]].push_back(C(2,deepth[MU[i].t]-MU[i].sum+1+ZAY,-1));
    }
    dfirsts(1,0);
    for(rg int i=1;i<n;++i) write(w[i].ans,' ',true);
    write(w[n].ans,'\n',true);
}

void dfirsts(ci u,ci fat) {
    int _temp=lft[deepth[u]+w[u].v]+rt[deepth[u]-w[u].v+ZAY];
    rg unsigned int _s=cg[u].size();
    for(rg unsigned i=0;i<_s;++i) {
        int _ud=cg[u][i].ud;
        if(_ud == 1) {
            lft[cg[u][i].v]+=cg[u][i].tp;
        }
        else rt[cg[u][i].v]+=cg[u][i].tp;
    }
    for(rg int i=hd[u];i;i=edge[i].nxt) if(edge[i].to != fat) 
        dfirsts(edge[i].to,u);
    w[u].ans=lft[deepth[u]+w[u].v]+rt[deepth[u]-w[u].v+ZAY]-_temp;
}

  

posted @ 2019-09-11 13:09  [jackeylove]  阅读(167)  评论(0编辑  收藏  举报