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 }

虽然还可以更快,但我不想打了

转载于:https://www.cnblogs.com/mzg1805/p/10772575.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值