标签:from define break pen gis fine getc || tchar
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; }
标签:from define break pen gis fine getc || tchar
原文地址:https://www.cnblogs.com/ainiyuling/p/11505708.html