P3806 【模板】点分治1
一道淀粉质的模版题,开始是暴力
1 #include <bits/stdc++.h> 2 #define up(i,l,r) for(register int i = (l); i <= (r); ++i) 3 #define dn(i,l,r) for(register int i = (l); i >= (r); --i) 4 #define ll long long 5 #define re register 6 using namespace std; 7 8 template <typename T> void in(T &x) { 9 x = 0; T f = 1; char ch = getchar(); 10 while(!isdigit(ch)) {if(ch == '-') f = -1; ch = getchar();} 11 while( isdigit(ch)) {x = 10 * x + ch - 48; ch = getchar();} 12 x *= f; 13 } 14 15 template <typename T> void out(T x) { 16 if(x < 0) x = -x , putchar('-'); 17 if(x > 9) out(x/10); 18 putchar(x%10 + 48); 19 } 20 //--------------------------------------------------------- 21 22 const int N = 10007; 23 24 int n,m; 25 26 struct edge { 27 int v,w,nxt; 28 }e[N<<1]; int tot,head[N]; 29 30 void add(int u,int v,int w) { 31 e[++tot].v = v; e[tot].w = w; e[tot].nxt = head[u]; head[u] = tot; 32 } 33 34 int Tsize,f[N],rt; 35 int size[N]; 36 bool vis[N]; 37 38 void get_rt(int u,int fa) { 39 size[u] = 1; f[u] = 0; 40 for(re int i = head[u];i ;i = e[i].nxt) { 41 int v = e[i].v; if(v == fa || vis[v]) continue; 42 get_rt(v,u); 43 size[u] += size[v]; f[u] = max(f[u],size[v]); 44 } 45 f[u] = max(f[u],Tsize - size[u]); 46 if(f[u] < f[rt]) rt = u; 47 } 48 49 int dis[N],cdis[N]; 50 int ans[102210101]; 51 int cnt; 52 53 void get_dis(int u,int fa) { 54 cdis[++cnt] = dis[u]; 55 for(re int i = head[u]; i; i = e[i].nxt) { 56 int v = e[i].v; if(v == fa || vis[v]) continue; 57 dis[v] = dis[u] + e[i].w; get_dis(v,u); 58 } 59 } 60 61 void calc(int u,int w) { 62 cnt = 0; get_dis(u,0); 63 up(i,1,cnt) { 64 up(j,1,cnt) { 65 if(i != j) 66 ans[cdis[i] + cdis[j]] += w; 67 } 68 } 69 } 70 71 void solve(int u) { 72 vis[u] = 1; dis[u] = 0; calc(u,1); 73 for(re int i = head[u]; i; i = e[i].nxt) { 74 int v = e[i].v; if(vis[v]) continue; 75 dis[v] = e[i].w; calc(v,-1); 76 Tsize = size[v]; rt = 0; 77 get_rt(v,0); solve(rt); 78 } 79 } 80 81 int main() { 82 in(n); in(m); int x,y,w; 83 up(i,1,n-1) { 84 in(x); in(y); in(w); 85 add(x,y,w); add(y,x,w); 86 } 87 Tsize = n,f[0] = n+1,rt = 0; 88 get_rt(1,0); solve(rt); 89 int k; 90 up(i,1,m) { 91 in(k); 92 if(ans[k]) printf("AYE\n"); 93 else printf("NAY\n"); 94 } 95 return 0; 96 }
然后我用了二分
1 #include <bits/stdc++.h> 2 #define up(i,l,r) for(register int i = (l); i <= (r); ++i) 3 #define dn(i,l,r) for(register int i = (l); i >= (r); --i) 4 #define ll long long 5 #define re register 6 using namespace std; 7 8 template <typename T> void in(T &x) { 9 x = 0; T f = 1; char ch = getchar(); 10 while(!isdigit(ch)) {if(ch == '-') f = -1; ch = getchar();} 11 while( isdigit(ch)) {x = 10 * x + ch - 48; ch = getchar();} 12 x *= f; 13 } 14 15 template <typename T> void out(T x) { 16 if(x < 0) x = -x , putchar('-'); 17 if(x > 9) out(x/10); 18 putchar(x%10 + 48); 19 } 20 //--------------------------------------------------------- 21 22 const int N = 10007; 23 24 int n,m; 25 26 struct edge { 27 int v,w,nxt; 28 }e[N<<1]; int tot,head[N]; 29 30 void add(int u,int v,int w) { 31 e[++tot].v = v; e[tot].w = w; e[tot].nxt = head[u]; head[u] = tot; 32 } 33 34 int Tsize,f[N],rt; 35 int size[N]; 36 bool vis[N]; 37 38 void get_rt(int u,int fa) { 39 size[u] = 1; f[u] = 0; 40 for(re int i = head[u];i ;i = e[i].nxt) { 41 int v = e[i].v; if(v == fa || vis[v]) continue; 42 get_rt(v,u); 43 size[u] += size[v]; f[u] = max(f[u],size[v]); 44 } 45 f[u] = max(f[u],Tsize - size[u]); 46 if(f[u] < f[rt]) rt = u; 47 } 48 49 int dis[N]; 50 int cnt; 51 int belong; 52 53 struct cur { 54 int dis,bl; 55 bool operator < (const cur &x) const { 56 return dis < x.dis; 57 } 58 }c[N]; 59 60 void get_dis(int u,int fa) { 61 c[++cnt] = (cur){dis[u],belong}; 62 for(re int i = head[u]; i; i = e[i].nxt) { 63 int v = e[i].v; if(v == fa || vis[v]) continue; 64 dis[v] = dis[u] + e[i].w; get_dis(v,u); 65 } 66 } 67 68 int binary(int x) { 69 int l = 1,r = cnt; int res = 0; 70 while(l <= r) { 71 int mid = (l+r)>>1; 72 if(x <= c[mid].dis) res = mid,r = mid - 1; 73 else l = mid + 1; 74 } 75 return res; 76 } 77 78 bool test[107]; 79 int flag; 80 int k[107]; 81 82 void calc(int u) { 83 cnt = 0; 84 85 for(re int i = head[u];i;i = e[i].nxt) { 86 int v = e[i].v; if(vis[v]) continue; 87 dis[v] = e[i].w; belong = v; get_dis(v,u); 88 } 89 90 c[++cnt] = (cur){0,0};//自己也算一个; 91 92 sort(c+1,c+cnt+1); 93 94 up(i,1,m) { 95 up(j,1,cnt) { 96 if(flag == 0) return; 97 if(test[i]) break; 98 int r = binary(k[i]-c[j].dis); 99 if(c[j].bl != c[r].bl && c[j].dis + c[r].dis == k[i]) { 100 test[i] = 1; flag -= i; break; 101 } 102 } 103 } 104 } 105 106 void solve(int u) { 107 if(flag == 0) return; 108 vis[u] = 1; dis[u] = 0; 109 calc(u); 110 for(re int i = head[u]; i; i = e[i].nxt) { 111 int v = e[i].v; if(vis[v]) continue; 112 Tsize = size[v]; rt = 0; 113 get_rt(v,0); solve(rt); 114 } 115 } 116 117 int main() { 118 in(n); in(m); int x,y,w; 119 120 up(i,1,n-1) { 121 in(x); in(y); in(w); 122 add(x,y,w); add(y,x,w); 123 } 124 up(i,1,m) in(k[i]); 125 126 flag = (m*(m+1))/2; 127 128 Tsize = n,f[0] = n+1,rt = 0; 129 get_rt(1,0); solve(rt); 130 131 up(i,1,m) { 132 if(test[i]) printf("AYE\n"); 133 else printf("NAY\n"); 134 } 135 136 return 0; 137 }
虽然还可以更快,但我不想打了