天天爱跑步

Posted ainiyuling

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了天天爱跑步相关的知识,希望对你有一定的参考价值。

题面

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;

  

以上是关于天天爱跑步的主要内容,如果未能解决你的问题,请参考以下文章

BZOJ 4719--天天爱跑步(LCA&差分)

CH6303 天天爱跑步

[luogu]P1600 天天爱跑步[LCA]

天天爱跑步[NOIP2016]

LCA+线段树 NOIP2016 天天爱跑步

P1600 天天爱跑步