传送门

题意:

路径有$-1,1$两种权值,求有多少路径满足权值和为$0$且有一个点将路径分成权值和为$0$的两段


第四节课本来想去上化学,然后快上课了这道题还没调出来.....可恶我想上化学

昨天两节语文课潸然的李煜讲座也没去听呜呜听说今天的语文课还有什么文艺活动又错过了呜呜

还是有思路的

点分治,考虑经过$u$的路径

首先保证权值和为$0$,记录$c[i]$为当前权值和为$i$的路径有几条

怎么满足有一个点呢?

$0+0=0$!!!

我们只要保证一段和$0$另一段自然也是$0$

所以补充保存的信息,

$c[i][0]$当前权值和为$0$且到$u$的路径上没有一段为$0$(就是没有祖先的权值和也为$i$,打标记就行了)的路径有几条

$c[i][1]$表示有......

然后每颗子树先更新答案再更新$c$就行了

然后一直$WA$.....

突然想到自己没有处理$u$的信息

然后改了也不对

然后发现打标记只是$=1\ =0$没有$++\ --$.....

改了还不对

参考黄学长的代码打了一份他的做法$AC$了,然后又开始找自己的错误

最后还是处理$u$的信息有问题,我直接用了$mark$因为我还以为$mark$只有$0,1$.......

还我化学

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long ll;
const int N=1e5+,INF=1e9+;
inline int read(){
char c=getchar();int x=,f=;
while(c<''||c>''){if(c=='-')f=-;c=getchar();}
while(c>=''&&c<=''){x=x*+c-'';c=getchar();}
return x*f;
}
int n,a,b,w;
struct edge{
int v,w,ne;
}e[N<<];
int h[N],cnt;
inline void ins(int u,int v,int w){
cnt++;
e[cnt].v=v;e[cnt].w=w;e[cnt].ne=h[u];h[u]=cnt;
cnt++;
e[cnt].v=u;e[cnt].w=w;e[cnt].ne=h[v];h[v]=cnt;
} int f[N],size[N],all,vis[N],root;
void dfsRt(int u,int fa){
size[u]=;f[u]=;
for(int i=h[u];i;i=e[i].ne){
int v=e[i].v;
if(vis[v]||v==fa) continue;
dfsRt(v,u);
size[u]+=size[v];
f[u]=max(f[u],size[v]);
}
f[u]=max(f[u],all-size[u]);
if(f[u]<f[root]) root=u;
}
int mark[N<<],Z=N,c[N<<][];
ll ans;
void dfsAns(int u,int fa,int now){
if(now==) ans+=c[Z][]+c[Z][] +(mark[Z]>=);
else{
if(mark[Z+now]) ans+=c[Z-now][]+c[Z-now][];
else ans+=c[Z-now][];
}
mark[Z+now]++;
for(int i=h[u];i;i=e[i].ne)
if(!vis[e[i].v]&&e[i].v!=fa) dfsAns(e[i].v,u,now+e[i].w);
mark[Z+now]--;
}
int st[N],top;
void dfsDee(int u,int fa,int now){
c[Z+now][mark[Z+now]>=]++;
st[++top]=Z+now;
mark[Z+now]++;
for(int i=h[u];i;i=e[i].ne)
if(!vis[e[i].v]&&e[i].v!=fa) dfsDee(e[i].v,u,now+e[i].w);
mark[Z+now]--;
}
void dfsSol(int u){
vis[u]=;
for(int i=h[u];i;i=e[i].ne)
if(!vis[e[i].v]) dfsAns(e[i].v,u,e[i].w),dfsDee(e[i].v,u,e[i].w); while(top) c[st[top]][]=c[st[top]][]=,top--;
for(int i=h[u];i;i=e[i].ne)
if(!vis[e[i].v]){
all=size[e[i].v];root=;
dfsRt(e[i].v,);
dfsSol(root);
}
}
int main(){
freopen("in","r",stdin);
n=read();
for(int i=;i<n;i++) a=read(),b=read(),w= read()==?-:,ins(a,b,w);
all=n;root=;f[]=INF;
dfsRt(,);
dfsSol(root);
printf("%lld",ans);
}

黄学长做法,本质上一样的

改进了一下后$1600ms$

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long ll;
const int N=1e5+,INF=1e9+;
inline int read(){
char c=getchar();int x=,f=;
while(c<''||c>''){if(c=='-')f=-;c=getchar();}
while(c>=''&&c<=''){x=x*+c-'';c=getchar();}
return x*f;
}
int n,a,b,w;
struct edge{
int v,w,ne;
}e[N<<];
int h[N],cnt;
inline void ins(int u,int v,int w){
cnt++;
e[cnt].v=v;e[cnt].w=w;e[cnt].ne=h[u];h[u]=cnt;
cnt++;
e[cnt].v=u;e[cnt].w=w;e[cnt].ne=h[v];h[v]=cnt;
} int f[N],size[N],all,vis[N],root;
void dfsRt(int u,int fa){
size[u]=;f[u]=;
for(int i=h[u];i;i=e[i].ne){
int v=e[i].v;
if(vis[v]||v==fa) continue;
dfsRt(v,u);
size[u]+=size[v];
f[u]=max(f[u],size[v]);
}
f[u]=max(f[u],all-size[u]);
if(f[u]<f[root]) root=u;
}
int mark[N<<],Z=N;
ll c[N<<][],d[N<<][];
ll ans;
int mx;
void dfsRun(int u,int fa,int now){
d[Z+now][mark[Z+now]>=]++;
mx=max(mx,abs(now));
mark[Z+now]++;
for(int i=h[u];i;i=e[i].ne)
if(!vis[e[i].v]&&e[i].v!=fa)
dfsRun(e[i].v,u,now+e[i].w);
mark[Z+now]--;
}
void dfsSol(int u){//printf("dfsSol %d\n",u);
vis[u]=;
c[Z][]=;
int mxmx=;
for(int i=h[u];i;i=e[i].ne)
if(!vis[e[i].v]){
mx=;
dfsRun(e[i].v,u,e[i].w);
mxmx=max(mxmx,mx);
ans+=(c[Z][]-)*d[Z][];
for(int j=-mx;j<=mx;j++)
ans+=c[Z-j][]*d[Z+j][]+
c[Z-j][]*d[Z+j][]+c[Z-j][]*d[Z+j][];
for(int j=Z-mx;j<=Z+mx;j++){
c[j][]+=d[j][];
c[j][]+=d[j][];
d[j][]=d[j][]=;
}
}
for(int i=Z-mxmx;i<=Z+mxmx;i++) c[i][]=c[i][]=;
for(int i=h[u];i;i=e[i].ne)
if(!vis[e[i].v]){
all=size[e[i].v];root=;
dfsRt(e[i].v,);
dfsSol(root);
}
}
int main(){
freopen("in","r",stdin);
n=read();
for(int i=;i<n;i++) a=read(),b=read(),w= read()==?-:,ins(a,b,w);
all=n;root=;f[]=INF;
dfsRt(,);
dfsSol(root);
printf("%lld",ans);
}

BZOJ 3697: 采药人的路径 [点分治] [我想上化学课]的更多相关文章

  1. BZOJ 3697: 采药人的路径 点分治

    好久不做点分治的题了,正好在联赛之前抓紧复习一下. 先把边权为 $0$ 的置为 $-1$.定义几个状态:$f[dis][0/1],g[dis][0/1]$ 其中 $f$ 代表在当前遍历的子树内的答案. ...

  2. bzoj 3697: 采药人的路径【点分治】

    点分治,设当前处理的块的重心为rt,预处理出每个子树中f[v][0/1]表示组合出.没组合出一对值v的链数(从当前儿子出发的链),能组合出一对v值就是可以有一个休息点 然后对于rt,经过rt且合法的路 ...

  3. [BZOJ 3697] 采药人的路径

    [题目链接] https://www.lydsy.com/JudgeOnline/problem.php?id=3697 [算法] 首先 , 将黑色的边变成1 ,白色的边变成-1 那么 , 问题就转化 ...

  4. 【BZOJ】3697: 采药人的路径

    3697: 采药人的路径 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 1718  Solved: 602[Submit][Status][Discu ...

  5. 【BZOJ3697】采药人的路径 点分治

    [BZOJ3697]采药人的路径 Description 采药人的药田是一个树状结构,每条路径上都种植着同种药材.采药人以自己对药材独到的见解,对每种药材进行了分类.大致分为两类,一种是阴性的,一种是 ...

  6. BZOJ 3697/3127 采药人的路径 (点分治)

    题目大意: 从前有一棵无向树,树上边权均为$0$或$1$,有一个采药人,他认为如果一条路径上边权为$0$和$1$的边数量相等,那么这条路径阴阳平衡.他想寻找一条合法的采药路径,保证阴阳平衡.然后他发现 ...

  7. BZOJ.3784.树上的路径(点分治 贪心 堆)

    BZOJ \(Description\) 给定一棵\(n\)个点的带权树,求树上\(\frac{n\times(n-1)}{2}\)条路径中,长度最大的\(m\)条路径的长度. \(n\leq5000 ...

  8. BZOJ3697采药人的路径——点分治

    题目描述 采药人的药田是一个树状结构,每条路径上都种植着同种药材.采药人以自己对药材独到的见解,对每种药材进行了分类.大致分为两类,一种是阴性的,一种是阳性的.采药人每天都要进行采药活动.他选择的路径 ...

  9. BZOJ3697:采药人的路径(点分治)

    Description 采药人的药田是一个树状结构,每条路径上都种植着同种药材. 采药人以自己对药材独到的见解,对每种药材进行了分类.大致分为两类,一种是阴性的,一种是阳性的. 采药人每天都要进行采药 ...

随机推荐

  1. 基于C#的数据库文件管理助手

    我们经常会遇到这样的问题,在数据库中的文件存放的是web格式或者是绝对路径,以及使用的是百度上传或者其他上传组件,造成了很多异步上传的冗余文件,如果客户需要我们导出企业官网中的产品图片,我们该如何处理 ...

  2. 邓_PHP面试2

    又开始搞php了,好多php知识忘记了,学习php的方法是看面试题 下面是我搜集的一份php的面试题目 1.用PHP打印出前一天的时间格式是2006-5-10 22:21:21(2分) echo da ...

  3. 版本控制——TortoiseSVN (4)多版本并行开发 B

    =================================版权声明================================= 版权声明:原创文章 禁止转载  请通过右侧公告中的“联系邮 ...

  4. [SinGuLaRiTy] 复习模板-数学

    [SinGuLaRiTy-1047] Copyright (c) SinGuLaRiTy 2017. All Rights Reserved. 质因数分解 void solve(int n) { == ...

  5. ublime Text 3安装与使用

    ublime Text 3安装与使用 工具 2015-07-30 10:46 0 34 工欲善其事,必先利其器.好的工具帮助我们节省大量的工作时间,好用的插件使工具更强大. 1. 下载 可以从官网 h ...

  6. arcgis地图服务之 identify 服务

    arcgis地图服务之 identify 服务 在近期的一次开发过程中,利用IdentityTask工具查询图层的时候,请求的参数中ImageDisplay的参数出现了错误,导致查询直接不能执行,百度 ...

  7. IOS @proporty 关键字(一)retain strong

    @interface User : NSObject @property (nonatomic,retain) NSString* tRetain; @property (nonatomic,assi ...

  8. mysql超出最大连接数解决方法

    遇到mysql超出最大连接数,相信不少人第一反应就是查看mysql进程,看有没有慢查询,当然这个做法是完全正确的!但是很多时候真正的问题不在这里.今天有遇到同样的问题,一味查看mysql进程和慢查询日 ...

  9. 序列化和Json

    实现了python与python程序之间内存的交互 常用场景: 1 把内存的数据写到磁盘 2 socket只能传字符串,二进制,通过序列化 ============================== ...

  10. linux中操作java进程

    通过 ps -ef|grep java 来得到真正运行的线程 通过kill -9 XXXXX来杀死正在运行的线程,其中XXXXX是上面java线程的序号. 另外还有2个指令我也不熟悉,一个是cat,一 ...