点分治

  点分治的例题2(本题代码结果为TLE……)

  强烈谴责卡时限QAQ,T了无数次啊无数次……

  不过在N次的静态查错中倒是加深了对点分治的理解……也算因祸得福吧(自我安慰一下)

TLE后的改进:每棵子树在重算f数组的时候,不要完全清空,而是清到最深深度即可。——>WA

 //SPOJ 1825
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#define rep(i,n) for(int i=0;i<n;++i)
#define F(i,j,n) for(int i=j;i<=n;++i)
#define D(i,j,n) for(int i=j;i>=n;--i)
using namespace std;
inline void read(int &v){
v=; int sign=; char ch=getchar();
while(ch<''||ch>''){ if (ch=='-') sign=-; ch=getchar();}
while(ch>=''&&ch<=''){ v=v*+ch-''; ch=getchar();}
v*=sign;
}
/******************tamplate*********************/
const int N=,INF=1e8;
int n,m,k,root=,h[N],s[N],g[N],f[N],size,d[N];
bool vis[N],black[N];
int to[N],head[N],next[N],len[N],tot=;
inline void ins(int x,int y,int l){
to[++tot]=y; next[tot]=head[x]; head[x]=tot; len[tot]=l;
to[++tot]=x; next[tot]=head[y]; head[y]=tot; len[tot]=l;
} inline void getroot(int x,int fa){
s[x]=;h[x]=;
for(int i=head[x];i;i=next[i])
if (to[i]!=fa && !vis[to[i]]){
getroot(to[i],x);
s[x]+=s[to[i]];
//h[x]=max(h[x],s[to[i]]);
if (s[to[i]]>h[x]) h[x]=s[to[i]];
}
h[x]=max(h[x],size-s[x]);
if (h[x]<h[root]) root=x;
} inline void getdep(int x,int fa){
int res=;
for(int i=head[x];i;i=next[i]){
if (to[i]!=fa && !vis[to[i]]){
d[to[i]]=d[x]+black[to[i]];
getdep(to[i],x);
res=max(res,d[to[i]]);
}
}
d[x]+=res;
}
inline void getg(int x,int fa,int leng,int c){
g[c]=max(g[c],leng);
for(int i=head[x];i;i=next[i])
if (to[i]!=fa && !vis[to[i]]) getg(to[i],x,leng+len[i],c+black[to[i]]);
}
struct node{int deep,to,len;}st[N];
inline bool cmp(const node &a,const node &b) {return a.deep<b.deep;}
int ans=,cnt; void getans(int x){
vis[x]=;
for(int i=head[x];i;i=next[i])
getdep(to[i],x);
cnt=;
F(i,,n) f[i]=;
for(int i=head[x];i;i=next[i]){
if (!vis[to[i]]){
d[to[i]]=black[to[i]];
getdep(to[i],x);
st[cnt++]=(node){d[to[i]],to[i],len[i]};
}
}
sort(st,st+cnt,cmp);
rep(i,cnt){
int y=st[i].to;
F(j,,d[y]) g[j]=-INF;
getg(y,x,st[i].len,black[y]);
if (i>){
int end=min(k-black[x],d[y]);
F(j,,end){
int p=min(d[st[i-].to],k-j-black[x]);
if (f[p]==-INF) break;
if (g[j]!=-INF) ans=max(ans,g[j]+f[p]);
}
}
F(j,,d[y]){
f[j]=max(f[j],g[j]);
if (j) f[j]=max(f[j],f[j-]);
if (j+black[x]<=k) ans=max(ans,f[j]);
}
} for(int i=head[x];i;i=next[i])
if (!vis[to[i]]){
root=; size=s[to[i]];
getroot(to[i],x);
getans(root);
}
} int main(){
// freopen("1825.in","r",stdin);
read(n); read(k); read(m);
int x,y,l;
F(i,,m){ read(x); black[x]|=;}
F(i,,n){
read(x); read(y); read(l);
ins(x,y,l);
}
root=; size=n; h[root]=INF;
getroot(,);
getans(root);
printf("%d\n",ans);
return ;
}

WA:deep要反过来求,d[x]表示以x为根的子树中黑点最长的路径(而不是从root到x经过了多少黑点)

  虽然好像原来的求法也能做不过不如这个方便(我一开始是写成两种混合了……QAQ)

RE:数组不能开20W,我改了个40W过了QAQ【iwtwiioi:双向边当然要开两倍的边集】!!!

 //SPOJ 1825
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#define rep(i,n) for(int i=0;i<n;++i)
#define F(i,j,n) for(int i=j;i<=n;++i)
#define D(i,j,n) for(int i=j;i>=n;--i)
using namespace std;
inline void read(int &v){
v=; int sign=; char ch=getchar();
while(ch<''||ch>''){ if (ch=='-') sign=-; ch=getchar();}
while(ch>=''&&ch<=''){ v=v*+ch-''; ch=getchar();}
v*=sign;
}
/******************tamplate*********************/
const int N=,INF=1e8;
int n,m,k,root=,h[N],s[N],g[N],f[N],size,d[N];
bool vis[N],black[N];
int to[N],head[N],next[N],len[N],tot=;
inline void ins(int x,int y,int l){
to[++tot]=y; next[tot]=head[x]; head[x]=tot; len[tot]=l;
to[++tot]=x; next[tot]=head[y]; head[y]=tot; len[tot]=l;
} inline void getroot(int x,int fa){
s[x]=;h[x]=;
for(int i=head[x];i;i=next[i])
if (to[i]!=fa && !vis[to[i]]){
getroot(to[i],x);
s[x]+=s[to[i]];
//h[x]=max(h[x],s[to[i]]);
if (s[to[i]]>h[x]) h[x]=s[to[i]];
}
h[x]=max(h[x],size-s[x]);
if (h[x]<h[root]) root=x;
} inline void getdep(int x,int fa){
int res=;
s[x]=; d[x]=black[x];
for(int i=head[x];i;i=next[i]){
if (to[i]!=fa && !vis[to[i]]){
getdep(to[i],x);
res=max(res,d[to[i]]);
s[x]+=s[to[i]];
}
}
d[x]+=res;//x为根的子树的最大“深度”
}
inline void getg(int x,int fa,int leng,int c){
g[c]=max(g[c],leng);
for(int i=head[x];i;i=next[i])
if (to[i]!=fa && !vis[to[i]])
getg(to[i],x,leng+len[i],c+black[to[i]]);
} inline bool cmp(int x,int y){
return d[to[x]]<d[to[y]];
}
int ans=,st[N],cnt; inline void getans(int x){
vis[x]=;//vis=1保证递归搜索子树时不会搜到当前节点
//对根的出边按dep排序
cnt=;
for(int i=head[x];i;i=next[i]){
if (!vis[to[i]]){
getdep(to[i],x);
st[cnt++]=i;
}
}
sort(st,st+cnt,cmp);
F(i,,d[to[st[cnt-]]]) f[i]=-INF;
rep(i,cnt){
int y=to[st[i]];
F(j,,d[y]) g[j]=-INF;
getg(y,x,len[st[i]],black[y]);
if (i>){
int end=min(k-black[x],d[y]);
F(j,,end){
int p=min(d[to[st[i-]]],k-j-black[x]);
if (f[p]==-INF) break;//!!!这里没懂
if (g[j]!=-INF) ans=max(ans,g[j]+f[p]);
}
}
F(j,,d[y]){
f[j]=max(f[j],g[j]);
if (j) f[j]=max(f[j],f[j-]);
if (j+black[x]<=k) ans=max(ans,f[j]);
}
} for(int i=head[x];i;i=next[i])
if (!vis[to[i]]){
root=; size=s[to[i]];
getroot(to[i],x);
getans(root);
}
} int main(){
#ifndef ONLINE_JUDGE
freopen("1825.in","r",stdin);
#endif
read(n); read(k); read(m);
int x,y,l;
F(i,,m){ read(x); black[x]|=;}
F(i,,n){
read(x); read(y); read(l);
ins(x,y,l);
}
root=; size=n; h[root]=INF;
getroot(,);
getans(root);
printf("%d\n",ans);
return ;
}

调了一天半终于出来了!锻炼了耐心和静态查错能力~

【SPOJ】【1825】Free Tour 2的更多相关文章

  1. 【SPOJ】1825. Free tour II(点分治)

    http://www.spoj.com/problems/FTOUR2/ 先前看了一会题解就自己yy出来了...对拍过后交tle.................. 自己造了下大数据........t ...

  2. 【 SPOJ - GRASSPLA】 Grass Planting (树链剖分+树状数组)

    54  种草约翰有 N 个牧场,编号为 1 到 N.它们之间有 N − 1 条道路,每条道路连接两个牧场.通过这些道路,所有牧场都是连通的.刚开始的时候,所有道路都是光秃秃的,没有青草.约翰会在一些道 ...

  3. 【SPOJ】NUMOFPAL - Number of Palindromes(Manacher,回文树)

    [SPOJ]NUMOFPAL - Number of Palindromes(Manacher,回文树) 题面 洛谷 求一个串中包含几个回文串 题解 Manacher傻逼题 只是用回文树写写而已.. ...

  4. 【SPOJ】Substrings(后缀自动机)

    [SPOJ]Substrings(后缀自动机) 题面 Vjudge 题意:给定一个长度为\(len\)的串,求出长度为1~len的子串中,出现最多的出现了多少次 题解 出现次数很好处理,就是\(rig ...

  5. 【SPOJ】Longest Common Substring II (后缀自动机)

    [SPOJ]Longest Common Substring II (后缀自动机) 题面 Vjudge 题意:求若干个串的最长公共子串 题解 对于某一个串构建\(SAM\) 每个串依次进行匹配 同时记 ...

  6. 【SPOJ】Longest Common Substring(后缀自动机)

    [SPOJ]Longest Common Substring(后缀自动机) 题面 Vjudge 题意:求两个串的最长公共子串 题解 \(SA\)的做法很简单 不再赘述 对于一个串构建\(SAM\) 另 ...

  7. 【SPOJ】Distinct Substrings(后缀自动机)

    [SPOJ]Distinct Substrings(后缀自动机) 题面 Vjudge 题意:求一个串的不同子串的数量 题解 对于这个串构建后缀自动机之后 我们知道每个串出现的次数就是\(right/e ...

  8. 【SPOJ】Distinct Substrings/New Distinct Substrings(后缀数组)

    [SPOJ]Distinct Substrings/New Distinct Substrings(后缀数组) 题面 Vjudge1 Vjudge2 题解 要求的是串的不同的子串个数 两道一模一样的题 ...

  9. 【SPOJ】Power Modulo Inverted(拓展BSGS)

    [SPOJ]Power Modulo Inverted(拓展BSGS) 题面 洛谷 求最小的\(y\) 满足 \[k\equiv x^y(mod\ z)\] 题解 拓展\(BSGS\)模板题 #inc ...

  10. 【SPOJ】QTREE7(Link-Cut Tree)

    [SPOJ]QTREE7(Link-Cut Tree) 题面 洛谷 Vjudge 题解 和QTREE6的本质是一样的:维护同色联通块 那么,QTREE6同理,对于两种颜色分别维护一棵\(LCT\) 每 ...

随机推荐

  1. java实现两台电脑间TCP协议文件传输

    记录下之前所做的客户端向服务端发送文件的小项目,总结下学习到的一些方法与思路. 注:本文参考自<黑马程序员>视频. 首先明确需求,在同一局域网下的机器人A想给喜欢了很久的机器人B发送情书, ...

  2. Linux-UDP-Socket编程

    接收CAN总线上的数据并将其发送出去 创建客户端: /******************************************************************** * co ...

  3. sublime text3安装Package Control和Vue Syntax Highlight

    一.下载Sublime3 https://www.sublimetext.com/3 二.安装Package Control 在线安装: https://packagecontrol.io/insta ...

  4. 支撑大规模公有云的Kubernetes改进与优化 (1)

    Kubernetes是设计用来实施私有容器云的,然而容器作为公有云,同样需要一个管理平台,在Swarm,Mesos,Kubernetes中,基于Kubernetes已经逐渐成为容器编排的最热最主流的平 ...

  5. Django url 标签和reverse()函数的使用(转)

    使用url标签和reverse()函数,可以避免在模板和view中对url进行硬编码,这样即使url改变了,对模板和view也没有影响, 其实在模板, view中,如果想获取当前访问的url,那用re ...

  6. 【十月のA Letter to 后辈菌】

    文化课没什么好说的,那就不说了吧(^▽^) 以下送给下两级的学弟学妹们: 马上就要NOIP了,现在自己从戏中人变成了看戏人.不管高一还是高二,我感觉只要能走到这一步就很了不起了,不管结果如何,比赛过程 ...

  7. Bzoj1018[SHOI2008]堵塞的交通traffic(线段树)

    这题需要维护连通性,看到有连接删除,很容易直接就想LCT了.然而这题点数20w操作10w,LCT卡常估计过不去.看到这个东西只有两行,考虑能否用魔改后的线性数据结构去维护.我想到了线段树. 考虑如果两 ...

  8. luoguP4491 [HAOI2018]染色 广义容斥原理 + FFT

    非常明显的摆了一个NTT模数.... 题目中求恰好\(k\),那么考虑求至少\(k\) 记\(g(k)\)表示至少\(k\)中颜色出现了恰好\(S\)次 那么,\[g(k) = \binom{M}{k ...

  9. luogu NOIp热身赛(2018-11-07)题解

    为什么前面的人都跑得那么快啊? QAQ T1:区间方差 题目大意:询问区间方差,支持单点修改 首先把方差的式子展开,得到 $$d = \frac{a_1 + ... a_n}{n} - \frac{a ...

  10. ShellExecuteA函数

    原型: ShellExecuteA(, , , );//最大化打开记事本 第一个参数//系统启动第二个参数//open打开第三个参数//指令第四个参数//默认0第五个参数//默认0第六个参数//0隐藏 ...