标签:
对于一条路径x-y:
·若x与y成祖先-孩子关系,假设y是x的祖先,z是y到x方向的第一个节点,则包含它的路径满足:起点在x的子树里,且终点不在z的子树里。
·若x与y不成祖先-孩子关系,则包含它的路径满足:起点在x的子树里,且终点在y的子树里。
于是每个盘子可以拆成一个或两个矩形,每个水果可以当成两个点。
整体二分的时候扫描线+树状数组维护,时间复杂度$O(n\log^2n)$。
#include<cstdio> #include<algorithm> #define N 40010 using namespace std; int n,m,Q,i,x,y,z,q[N],tmp[N],now[N],ans[N],T,pos[N],bit[N]; int g[N],nxt[N<<1],v[N<<1],ed,d[N],size[N],son[N],top[N],f[N],st[N],en[N],dfn; struct E{ int x1,x2,l1,r1,l2,r2,z; E(){} E(int _x1,int _x2,int _l1,int _r1,int _l2,int _r2,int _z){ x1=_x1,x2=_x2,l1=_l1,r1=_r1,l2=_l2,r2=_r2,z=_z; } }e[N]; inline bool cmp(const E&a,const E&b){return a.z<b.z;} struct P{int x,y,k,p;P(){}P(int _x,int _y,int _k,int _p){x=_x,y=_y,k=_k,p=_p;}}a[N]; struct B{int x,l,r,t;B(){}B(int _x,int _l,int _r,int _t){x=_x,l=_l,r=_r,t=_t;}}b[N<<1]; inline bool cmpb(const B&a,const B&b){return a.x<b.x;} struct C{int x,y,p;C(){}C(int _x,int _y,int _p){x=_x,y=_y,p=_p;}}c[N<<1]; inline bool cmpc(const C&a,const C&b){return a.x<b.x;} inline void addedge(int x,int y){v[++ed]=y;nxt[ed]=g[x];g[x]=ed;} void dfs(int x){ size[x]=1; for(int i=g[x];i;i=nxt[i])if(v[i]!=f[x]){ d[v[i]]=d[f[v[i]]=x]+1;dfs(v[i]);size[x]+=size[v[i]]; if(size[v[i]]>size[son[x]])son[x]=v[i]; } } void dfs2(int x,int y){ st[x]=++dfn;top[x]=y; if(son[x])dfs2(son[x],y); for(int i=g[x];i;i=nxt[i])if(v[i]!=son[x]&&v[i]!=f[x])dfs2(v[i],v[i]); en[x]=dfn; } inline int lca2(int x,int y){ int t; while(top[x]!=top[y])t=top[y],y=f[top[y]]; return x==y?t:son[x]; } inline void add(int x,int p){for(;x<=n;x+=x&-x)if(pos[x]<T)pos[x]=T,bit[x]=p;else bit[x]+=p;} inline int ask(int x){int t=0;for(;x;x-=x&-x)if(pos[x]==T)t+=bit[x];return t;} void solve(int l,int r,int h,int t){ if(h>t)return; if(l==r){ for(int i=h;i<=t;i++)ans[a[q[i]].p]=e[l].z; return; } int mid=(l+r)>>1,cb=0,cc=0; for(int i=l;i<=mid;i++){ if(e[i].l1<=e[i].r1){ b[cb++]=B(e[i].x1,e[i].l1,e[i].r1,1); b[cb++]=B(e[i].x2+1,e[i].l1,e[i].r1,-1); } if(e[i].l2<=e[i].r2){ b[cb++]=B(e[i].x1,e[i].l2,e[i].r2,1); b[cb++]=B(e[i].x2+1,e[i].l2,e[i].r2,-1); } } for(int i=h;i<=t;i++){ c[cc++]=C(a[q[i]].x,a[q[i]].y,i); c[cc++]=C(a[q[i]].y,a[q[i]].x,i); now[i]=0; } T++,sort(b,b+cb,cmpb),sort(c,c+cc,cmpc); for(int i=0,j=0;i<cc;i++){ while(j<cb&&b[j].x<=c[i].x)add(b[j].l,b[j].t),add(b[j].r+1,-b[j].t),j++; now[c[i].p]+=ask(c[i].y); } int L=h,R=t; for(int i=h;i<=t;i++)if(now[i]>=a[q[i]].k)tmp[L++]=q[i];else a[q[i]].k-=now[i],tmp[R--]=q[i]; for(int i=h;i<=t;i++)q[i]=tmp[i]; solve(l,mid,h,R),solve(mid+1,r,R+1,t); } inline void read(int&a){char c;while(!(((c=getchar())>=‘0‘)&&(c<=‘9‘)));a=c-‘0‘;while(((c=getchar())>=‘0‘)&&(c<=‘9‘))(a*=10)+=c-‘0‘;} int main(){ read(n),read(m),read(Q); for(i=1;i<n;i++)read(x),read(y),addedge(x,y),addedge(y,x); dfs(1),dfs2(1,1); for(i=1;i<=m;i++){ read(x),read(y),read(z); if(d[x]<d[y])swap(x,y); if(st[y]<=st[x]&&en[x]<=en[y])y=lca2(y,x),e[i]=E(st[x],en[x],1,st[y]-1,en[y]+1,n,z); else e[i]=E(st[x],en[x],st[y],en[y],1,0,z); } sort(e+1,e+m+1,cmp); for(i=1;i<=Q;i++){ q[i]=i; read(x),read(y),read(z); a[i]=P(st[x],st[y],z,i); } solve(1,m,1,Q); for(i=1;i<=Q;i++)printf("%d\n",ans[i]); return 0; }
标签:
原文地址:http://www.cnblogs.com/clrs97/p/4792787.html