P1600 天天愛跑步
阿新 • • 發佈:2018-09-20
deb sin prior bool tin find deep tdi %d lca真心不太會,這裏只介紹60分做法,100的太
lca真心不太會,這裏只介紹60分做法,100的太難辣簡單了就不介紹了
n<=1000
zz回溯爆搜
S[i]全部相等
這dfs序都不用lca的,2333,差分,然後輸出判斷一下是否是0(1到i的時間是固定的)
退化成一條鏈子
一個點i的ans就是i-time[i]和i+tim[i]的起點個數(當然要合法啦)
亂搞就好了,這裏寫的nlogn的
#include <iostream> #include <queue> #include <cstdio> #include <cstring> using namespace std; const int maxn=300000; const int maxn_25=1000; struct edge { int v,nxt; }e[maxn<<1]; struct node { int x,id; bool operator < (const node b) const { return x>b.x; } }; struct node1 { int x,id; bool operator < (const node1 b) const { return x<b.x; } }; int head[maxn<<1],tot; int tim[maxn],n,m,S[maxn],T[maxn],deep[maxn<<1]; int pd_25,ans_25[maxn_25]; //baoli 25 zhuanyong int tot_a,a_c[maxn<<1],find_a[maxn],ans_c[maxn];//all s == 1 zhuanyong int vis[maxn<<1],cf[maxn<<1],dsr[maxn<<1]; int ans[maxn]; void add_edge(int u,int v) { e[++tot].v=v; e[tot].nxt=head[u]; head[u]=tot; } inline int read() { int x=0,f=1;char s=getchar(); while(s<'0'||s>'9') {if(s=='-')f=-1;s=getchar();} while(s>='0'&&s<='9') {x=(x<<3)+(x<<1)+s-'0',s=getchar();} return x*f; } void dfs_25(int u,int f,int end,int cnt) { if(u==end) { if(cnt==tim[u]) ans_25[u]++; pd_25=1; return; } if(pd_25) return; if(cnt==tim[u]) ans_25[u]++; for(int i=head[u];i;i=e[i].nxt) { int v=e[i].v; if(v==f) continue; dfs_25(v,u,end,cnt+1); if(pd_25) return; } if(cnt==tim[u]) ans_25[u]--; } void dfs_deep(int u,int f,int cnt) { deep[u]=cnt; for(int i=head[u];i;i=e[i].nxt) { int v=e[i].v; if(f==v) continue; dfs_deep(v,u,cnt+1); } } void dfs_xu(int u,int f) { a_c[++tot_a]=0; find_a[u]=tot_a; for(int i=head[u];i;i=e[i].nxt) { int v=e[i].v; if(v==f) continue; dfs_xu(v,u); } a_c[++tot_a]=0; vis[tot_a]=u; dsr[u]=tot_a; } int main() { n=read(),m=read(); for(int i=1;i<n;++i) { int x=read(),y=read(); add_edge(x,y); add_edge(y,x); } for(int i=1;i<=n;++i) tim[i]=read(); for(int i=1;i<=m;++i) S[i]=read(),T[i]=read(); //baoli_25 if(n<=1000) { for(int i=1;i<=m;++i) { pd_25=0; dfs_25(S[i],0,T[i],0); } for(int j=1;j<=n;++j) printf("%d ",ans_25[j]); return 0; } int wakaka=1; for(int i=1;i<=m;++i) if(S[i]!=1) wakaka=0; if(wakaka) { //all S[i]==1 fen==20 dfs_deep(1,0,0);//1 -> i deep dfs_xu(1,0); //chafen for(int i=1;i<=m;++i) { //1->i cf[find_a[S[i]]]++; cf[find_a[T[i]]+1]--; } //qiouhe for(int i=1;i<=tot_a;++i) { a_c[i]=a_c[i-1]+cf[i]; } for(int i=1;i<=n;++i) { if(deep[i]==tim[i]) printf("%d ",a_c[find_a[i]]-a_c[dsr[i]]); else printf("0 "); } return 0; } priority_queue<node> q; for(int i=1;i<=m;++i) { if(S[i] > T[i]) continue; dsr[S[i]]++; node x; x.x=T[i]+1; x.id=S[i]; q.push(x); } for(int i=1;i<=n;++i) { while(!q.empty()&&q.top().x==i) dsr[q.top().id]--,q.pop(); if(i-tim[i]>=1) ans[i]+=dsr[i-tim[i]]; } priority_queue< node1 > qq; memset(dsr,0,sizeof(dsr)); for(int i=1;i<=m;++i) { if(S[i] <= T[i]) continue; dsr[S[i]]++; node1 x; x.x=T[i]-1; x.id=S[i]; qq.push(x); } for(int i=n;i>=1;--i) { while(!qq.empty()&&qq.top().x==i) dsr[qq.top().id]--,qq.pop(); // puts("debug"); // for(int j=1;j<=n;++j) // cout<<dsr[j]<<" ";puts(""); if(i+tim[i]<=n) ans[i]+=dsr[i+tim[i]]; } for(int i=1;i<=n;++i) printf("%d ",ans[i]); return 0; }
P1600 天天愛跑步