传送门

题意:

路径有$-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+5,INF=1e9+5;
inline int read(){char c=getchar();int x=0,f=1;while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}return x*f;
}
int n,a,b,w;
struct edge{int v,w,ne;
}e[N<<1];
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]=1;f[u]=0;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<<1],Z=N,c[N<<1][2];
ll ans;
void dfsAns(int u,int fa,int now){if(now==0) ans+=c[Z][0]+c[Z][1] +(mark[Z]>=1);else{if(mark[Z+now]) ans+=c[Z-now][0]+c[Z-now][1];else ans+=c[Z-now][1];}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]>=1]++;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]=1;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]][0]=c[st[top]][1]=0,top--;for(int i=h[u];i;i=e[i].ne) if(!vis[e[i].v]){all=size[e[i].v];root=0;dfsRt(e[i].v,0);dfsSol(root);}
}
int main(){freopen("in","r",stdin);n=read();for(int i=1;i<n;i++) a=read(),b=read(),w= read()==0?-1:1,ins(a,b,w);all=n;root=0;f[0]=INF;dfsRt(1,0);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+5,INF=1e9+5;
inline int read(){char c=getchar();int x=0,f=1;while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}return x*f;
}
int n,a,b,w;
struct edge{int v,w,ne;
}e[N<<1];
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]=1;f[u]=0;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<<1],Z=N;
ll c[N<<1][2],d[N<<1][2];
ll ans;
int mx;
void dfsRun(int u,int fa,int now){d[Z+now][mark[Z+now]>=1]++;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]=1;c[Z][0]=1;int mxmx=0;for(int i=h[u];i;i=e[i].ne)if(!vis[e[i].v]){mx=1;dfsRun(e[i].v,u,e[i].w);mxmx=max(mxmx,mx);ans+=(c[Z][0]-1)*d[Z][0];for(int j=-mx;j<=mx;j++) ans+=c[Z-j][1]*d[Z+j][1]+c[Z-j][0]*d[Z+j][1]+c[Z-j][1]*d[Z+j][0];for(int j=Z-mx;j<=Z+mx;j++){c[j][0]+=d[j][0];c[j][1]+=d[j][1];d[j][0]=d[j][1]=0;}}for(int i=Z-mxmx;i<=Z+mxmx;i++) c[i][0]=c[i][1]=0;for(int i=h[u];i;i=e[i].ne) if(!vis[e[i].v]){all=size[e[i].v];root=0;dfsRt(e[i].v,0);dfsSol(root);}
}
int main(){freopen("in","r",stdin);n=read();for(int i=1;i<n;i++) a=read(),b=read(),w= read()==0?-1:1,ins(a,b,w);all=n;root=0;f[0]=INF;dfsRt(1,0);dfsSol(root);printf("%lld",ans);
}

转载于:https://www.cnblogs.com/candy99/p/6497858.html

BZOJ 3697: 采药人的路径 [点分治] [我想上化学课]相关推荐

  1. bzoj千题计划248:bzoj3697: 采药人的路径

    http://www.lydsy.com/JudgeOnline/problem.php?id=3697 点分治 路径0改为路径-1 g[i][0/1] 和 f[i][0/1]分别表示当前子树 和 已 ...

  2. BZOJ 1176[Balkan2007]Mokia (cdq分治,矩阵加矩阵求和)

    BZOJ 1176[Balkan2007]Mokia (cdq分治,矩阵加矩阵求和) Description 维护一个W*W的矩阵,初始值均为S.每次操作可以增加某格子的权值,或询问某子矩阵的总权值. ...

  3. BZOJ - 2244 拦截导弹 (dp,CDQ分治+树状数组优化)

    BZOJ - 2244 拦截导弹 (dp,CDQ分治+树状数组优化) 1 #include<algorithm> 2 #include<iostream> 3 #include ...

  4. 未找到导入的项目 .wpp.targets。请确认 Import 声明中的路径正确,且磁盘上存在该文件

        今天打开vs突然报了一个错......... .wpp.targets.请确认 <Import> 声明中的路径正确,且磁盘上存在该文件 重新新建一个项目,dll全部都是黄色感叹号 ...

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

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

  6. bzoj3697 采药人的路径

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

  7. BZOJ.4598.[SDOI2016]模式字符串(点分治 Hash)

    LOJ BZOJ 洛谷 点分治.考虑如何计算过\(rt\)的答案. 记\(pre[i]\)表示(之前的)子树内循环匹配了\(S\)的前缀\(i\)的路径有多少,\(suf[i]\)表示(之前的)子树内 ...

  8. 【BZOJ】2599: [IOI2011]Race 点分治

    [题意]给一棵树,每条边有权.求一条简单路径,权值和等于K,且边的数量最小.N <= 200000, K <= 1000000.注意点从0开始编号,无解输出-1. [算法]点分治 [题解] ...

  9. bzoj3784 树上的路径 点分治+RMQ+优先队列

    题目分析 树上的路径路径?可以,这很点分治. 求最长的mmm条的长度?可以,着很优先队列. 但问题是,用优先队列只能做全局才能保证复杂度是对的,但点分治是分治就不能做全局. 于是对于每次点分治,都记录 ...

最新文章

  1. VML编程之------VML语言入门《VML极道教程》原著:沐缘华
  2. 03-cmake语法-变量,字符串
  3. jsp servlet示例_Servlet和JSP中的文件上传示例
  4. Python3 爬虫学习笔记 C13【验证码对抗系列 — 滑动验证码】
  5. ab的plc跟西门子哪个好些_2020滚筒洗衣机哪个牌子好?想买滚筒洗衣机的看过来!...
  6. 【剑指offer】面试题24:反转链表(Java)
  7. 互联网前景如何,还值得进入嘛?
  8. oracle10g配置失败,求解决装oracle10g的时候EM配置失败问题
  9. 优秀的代码永垂不朽!
  10. CCF201812-2 小明放学(100分)【序列处理】
  11. 客户端的云桌面平台配置与开启(附,登录“云电脑”与切换登录账号)
  12. Counting Stars HDU - 6184
  13. 更新显卡驱动后,Windows重启卡在Logo页面
  14. 论黑客必知DOS命令技术大拳!
  15. JQuery 日期选择框,精确到时分秒类型。
  16. 白菜u盘安装linux,使用U盘安装ubuntu 12.04(使用大白菜u盘启动工具)
  17. ASP木马Webshell安全解决办案
  18. KVM是什么 机柜 机架服务器 怎么用
  19. 决策树(Decision Tree)算法原理总结(一)
  20. 转载: windows硬盘默认是NTFS文件格式

热门文章

  1. 前端白屏问题_深入理解前端性能监控
  2. 个人计算机的组成及相关功能,计算机的组成部分及功能(范文).doc
  3. C语言指针怎么存二维数组,C语言怎么用指针代替二维数组
  4. java swing linux_Linux下关于解决JavaSwing中文乱码的情况
  5. pic pwm 占空比可调 源码_PIC16F914输出可调占空比PWM波形程序
  6. pitr 原理_PostgreSQL基于时间点恢复(PITR)
  7. 360浏览器查看html文件在哪里,360浏览器8菜单栏怎么弄出来?如何查看网站源代码...
  8. 计算机网络又称为分时多用户,7计算机网络原理期末复习试卷A卷.doc
  9. bert关键词提取_BERT可以上几年级了?Seq2Seq“硬刚”小学数学应用题
  10. linux中开启514端口,linux中开启指定端口