传送门

题意:

路径有$-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. [国嵌攻略][068][tftp网络协议实现]

    IP协议结构 UDP协议结构 TFTP协议结构 TFTP端口 读写请求端口: 69 其他请求端口:1024~65535 主程序 /*********************************** ...

  2. 从零开始学习前端开发 — 15、CSS3过渡、动画

    一.css3过渡 语法: transition: 过渡属性 过渡时间 延迟时间 过渡方式; 1.过渡属性(transition-property) 取值:all 所有发生变化的css属性都添加过渡 e ...

  3. HTTP协议简介

    一.简介 HTTP(HyperText Transfer Protocol, 超文本传输协议) 是访问互联网使用的核心通信协议,也是所有web应用程序使用的通信协议.消息模型:客户端发送请求消息,服务 ...

  4. win7彻底卸载iis

    https://jingyan.baidu.com/article/e5c39bf5829e8e39d660336c.html 昨天在电脑上搭建了PHP开发环境之后,重启apache服务器老是报错,检 ...

  5. electron 学习笔记

    一.快速搭建一个electron 项目结构 # 克隆示例项目的仓库 $ git clone https://github.com/electron/electron-quick-start # 进入这 ...

  6. Uva10129 - Play on Words 欧拉通路 DFS

    题目链接: http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=105& ...

  7. Java数据结构和算法(十三)——哈希表

    Hash表也称散列表,也有直接译作哈希表,Hash表是一种根据关键字值(key - value)而直接进行访问的数据结构.它基于数组,通过把关键字映射到数组的某个下标来加快查找速度,但是又和数组.链表 ...

  8. 利用H5构建地图和获取定位地点

    地图与地理定位 定位在大部分项目中都需要实现,如何实现主要有如下的几种方法 H5定位 在HTML5中navigator有很强大的功能,其中就有定位的方法 navigator.geolocation.g ...

  9. Tomcat系统架构分析

    Tomcat系统架构分析 关于这边blog呢,实际开发中并不会用到,但是我觉得还是很有必要认真的写一下.毕竟我们每天在本地撸码的时候使用的就是tomcat来做web服务器.一个常识就是说我们本地在to ...

  10. 添加FTP用户(vsftpd)

    1.环境:ftp为vsftp. 用户名为test.默认路径为/home/test 2.新建用户(当前是root用户) 运行命令:"useradd -d /home/test test&quo ...