「点分治练习」boatherds
「问题描述」
询问一颗树上距离为 K 的点对是否存在
「输入格式」
第一行两个整数 n,m
接下来 n-1 条边 a,b,c 描述 a 到 b 有一条长度为 c 的路径 接下来 m 行每行询问一个 K
「输出格式」
对于每个 K 每行输出一个答案
存在输出”AYE”, 否则输出”NYE”(不包含引号)
「样例输入」
2 2
1 2 1
1
2
「样例输出」
AYE
NYE
「数据规模与约定」
对于 30% 的数据,有 1 ≤ n ≤ 100
对于 60% 的数据,有 1 ≤ n ≤ 10^3 1 ≤ m ≤ 50
对于100%的数据,有1≤n≤10^4,1≤m≤100,1≤c≤1000,1≤K≤10^7
「题解」
czy神犇良心出题照顾蒟蒻
点分治的时候暴力枚举一下a_i,在set中查询
复杂度O(nmlogn^2)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 |
#include<iostream> #include<cstdio> #include<algorithm> #include<cmath> #include<set> #include<vector> #define ll long long using namespace std; inline int read() { int x=0;char ch=getchar(); while(ch<'0'||ch>'9')ch=getchar(); while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} return x; } int n,m,cnt,rt,sum,top; int f[10005],size[10005],dis[10005]; int a[105],tmp[10005],last[10005]; set<int> st; bool ans[105],vis[10005]; struct edge{ int to,next,v; }e[20005]; void insert(int u,int v,int w) { e[++cnt].to=v;e[cnt].next=last[u];last[u]=cnt;e[cnt].v=w; e[++cnt].to=u;e[cnt].next=last[v];last[v]=cnt;e[cnt].v=w; } void getrt(int x,int fa) { f[x]=0;size[x]=1; for(int i=last[x];i;i=e[i].next) if(!vis[e[i].to]&&e[i].to!=fa) { getrt(e[i].to,x); size[x]+=size[e[i].to]; f[x]=max(f[x],size[e[i].to]); } f[x]=max(f[x],sum-size[x]); if(f[x]<f[rt])rt=x; } void dfs(int x,int fa) { tmp[++top]=dis[x]; for(int i=last[x];i;i=e[i].next) if(!vis[e[i].to]&&e[i].to!=fa) { dis[e[i].to]=dis[x]+e[i].v; dfs(e[i].to,x); } } void query(int x) { for(int i=1;i<=m;i++) if(!ans[i]) { int K=a[i]; if(*st.lower_bound(K-x)==K-x) ans[i]=1; } } void solve(int x) { vis[x]=1; st.clear();st.insert(0); for(int i=last[x];i;i=e[i].next) if(!vis[e[i].to]) { top=0; dis[e[i].to]=e[i].v; dfs(e[i].to,x); for(int j=1;j<=top;j++)query(tmp[j]); for(int j=1;j<=top;j++)st.insert(tmp[j]); } for(int i=last[x];i;i=e[i].next) if(!vis[e[i].to]) { rt=0;sum=size[e[i].to]; getrt(e[i].to,0); solve(rt); } } int main() { // freopen("boatherds.in","r",stdin); // freopen("boatherds.out","w",stdout); n=read();m=read(); for(int i=1;i<n;i++) { int u=read(),v=read(),w=read(); insert(u,v,w); } for(int i=1;i<=m;i++)a[i]=read(); rt=0;sum=n;f[0]=n+1; getrt(1,0); solve(rt); for(int i=1;i<=m;i++) if(ans[i])puts("AYE"); else puts("NAY"); return 0; } |
黄学长,您的代码似乎有些问题
3 1
1 2 4
1 3 1
2