1.树上点分治。
第一次手写AC点分治呢。bzoj1316
#include<bits/stdc++.h> using namespace std; #define N 10010 set<int> s; bool ans [110]; 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; struct E{ int next,to,cal; }e[N<<1]; int head[N],siz[N],son[N],root,sum,minn,q[110]; bool vis[N]; int cnt; inline void add(int u,int v,int c){ e[++cnt].to=v;e[cnt].cal=c;e[cnt].next=head[u];head[u]=cnt; } void findroot(int u,int fa){ siz[u]=1,son[u]=0; for(int i=head[u];i;i=e[i].next){ int v=e[i].to; if(vis[v]||v==fa)continue; findroot(v,u); siz[u]+=siz[v]; son[u]=max(son[u],siz[v]); } int ret=max(sum-siz[u],son[u]); if(ret<minn)minn=ret,root=u; } void getans(int u,int fa,int cal){ for(int i=1;i<=m;i++){ if(s.find(q[i]-cal)!=s.end())ans[i]=1; } for(int i=head[u];i;i=e[i].next){ int v=e[i].to; if(vis[v]||v==fa)continue; getans(v,u,cal+e[i].cal); } } void ad(int u,int fa,int cal){ s.insert(cal); for(int i=head[u];i;i=e[i].next){ int v=e[i].to; if(vis[v]||v==fa)continue; ad(v,u,cal+e[i].cal); } } void solve(int u){ vis[u]=1; minn=n;s.clear(); for(int i=head[u];i;i=e[i].next){ int v=e[i].to; if(vis[v])continue; getans(v,u,e[i].cal); ad(v,u,e[i].cal); } for(int i=1;i<=m;i++)if(s.find(q[i])!=s.end())ans[i]=1; for(int i=head[u];i;i=e[i].next){ int v=e[i].to; if(!vis[v]){ sum=siz[v];root=0;minn=n; findroot(v,u); solve(root); } } } int main(){ n=read(),m=read(); int u,v,c; for(int i=1;i<n;i++){ u=read(),v=read(),c=read(); add(u,v,c);add(v,u,c); } for(int i=1;i<=m;i++)q[i]=read(); sum=n,minn=n; findroot(1,0); solve(root); for (int i=1;i<=m;i++) if (ans[i]||q[i]==0) puts("Yes"); else puts("No"); return 0; }
最近又练了好多点分治的题,得出一个结论。
我的大代码能力还是有待提高啊。
(1)我不愿意打太长的代码
(2)长的代码我很难调试
这两点导致很多大代码题有时候半途而废,或者挑不出来一直搁置。
我该怎么样提高我的代码能力呢。。
2.计算几何