传送门

不是那么裸的点分治。

$f[i][0/1]$表示当前节点的一个子树中总权值和为$i$,且是否存在一个前缀使得其前缀和为$i$

$g[i][0/1]$表示当前节点的已遍历过的子树,其余一样。

对于每个节点

$ans_{node}=g[0][0]∗f[0][0]+ \sum (g[−i][0]∗f[i][1]+g[−i][1]∗f[i][0]+g[−i][1]∗f[i][1])$

另外,Race那道题选根的方案在这里好像不是很适用,容易出问题,还是换黄学长的比较好。

 //BZOJ 3697
 //by Cydiater
 //2016.9.26
 #include <iostream>
 #include <cstdio>
 #include <cstring>
 #include <string>
 #include <algorithm>
 #include <queue>
 #include <map>
 #include <ctime>
 #include <cmath>
 #include <iomanip>
 #include <cstdlib>
 using namespace std;
 #define ll long long
 #define up(i,j,n)       for(int i=j;i<=n;i++)
 #define down(i,j,n)     for(int i=j;i>=n;i--)
 ;
 const int oo=0x3f3f3f3f;
 inline int read(){
     ,f=;
     ;ch=getchar();}
     +ch-';ch=getchar();}
     return x*f;
 }
 ,sum,root,siz[MAXN],dis[MAXN],pre[MAXN],deep[MAXN];
 int maxdeep,max_siz[MAXN];
 ll ans=,f[MAXN][],g[MAXN][];
 bool vis[MAXN];
 struct edge{
     int y,next,v;
 }e[MAXN];
 namespace solution{
     inline void insert(int x,int y,int v){e[++len].next=LINK[x];LINK[x]=len;e[len].y=y;e[len].v=v;}
     void init(){
         N=read();
         up(i,,N){
             ll x=read(),y=read(),v=read()==?-:;
             insert(x,y,v);
             insert(y,x,v);
         }
     }
     void make_root(int node,int fa){
         max_siz[node]=;siz[node]=;
         for(int i=LINK[node];i;i=e[i].next)if(!vis[e[i].y]&&e[i].y!=fa){
             make_root(e[i].y,node);
             siz[node]+=siz[e[i].y];
             max_siz[node]=max(max_siz[node],siz[e[i].y]);
         }
         max_siz[node]=max(max_siz[node],sum-max_siz[node]);
         if(max_siz[node]<max_siz[root])root=node;
     }
     void dfs(int node,int father){
         ]++;
         ]++;
         pre[dis[node]]++;
         maxdeep=max(deep[node],maxdeep);
         for(int i=LINK[node];i;i=e[i].next)
             if(e[i].y!=father&&!vis[e[i].y]){
                 deep[e[i].y]=deep[node]+;
                 dis[e[i].y]=dis[node]+e[i].v;
                 dfs(e[i].y,node);
             }
         pre[dis[node]]--;
     }
     void work(int node){
         vis[node]=;g[N][]=;;
         for(int i=LINK[node];i;i=e[i].next)if(!vis[e[i].y]){
             dis[e[i].y]=e[i].v+N;deep[e[i].y]=;maxdeep=;
             dfs(e[i].y,);mx=max(mx,maxdeep);
             ans+=1LL*(g[N][]-)*f[N][];
             up(k,-maxdeep,maxdeep)
                 ans+=1LL*g[N-k][]*f[N+k][]+1LL*g[N-k][]*f[N+k][]+1LL*g[N-k][]*f[N+k][];
             up(j,N-maxdeep,N+maxdeep){
                 g[j][]+=f[j][];
                 g[j][]+=f[j][];
                 f[j][]=f[j][]=;
             }
         }
         up(j,N-mx,N+mx)g[j][]=g[j][]=;
         for(int i=LINK[node];i;i=e[i].next)if(!vis[e[i].y]){
             root=;sum=siz[e[i].y];
             make_root(e[i].y,);
             work(root);
         }
     }
     void slove(){
         sum=N;root=;max_siz[root]=N;
         make_root(,);
         work(root);
     }
     void output(){
         cout<<ans<<endl;
     }
 }
 int main(){
     //freopen("input.in","r",stdin);
     using namespace solution;
     init();
     slove();
     output();
     ;
 }

BZOJ3697: 采药人的路径的更多相关文章

  1. [bzoj3697]采药人的路径_点分治

    采药人的路径 bzoj-3697 题目大意:给你一个n个节点的树,每条边分为阴性和阳性,求满足条件的链的个数,使得这条链上阴性的边的条数等于阳性的边的条数,且这条链上存在一个节点,这个节点到一个端点的 ...

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

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

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

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

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

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

  5. [bzoj3697]采药人的路径——点分治

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

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

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

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

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

  8. 2019.01.09 bzoj3697: 采药人的路径(点分治)

    传送门 点分治好题. 题意:给出一棵树,边分两种,求满足由两条两种边数相等的路径拼成的路径数. 思路: 考虑将边的种类转化成边权−1-1−1和111,这样就只用考虑由两条权值为000的路径拼成的路径数 ...

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

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

随机推荐

  1. jQuery 插件编程精讲与技巧

    适应的读者: 1.有一定的jquery编程基础但是想在技能上有所提升的人 2.前端开发的程序员 3.对编程感兴趣的学生 为什么要学习jquery插件的编写? 为什么要学习jquery插件的编写?相信这 ...

  2. nios II--实验3——led 100M软件部分

    软件开发 参照实验二(led),该实验与实验二(led)的不同之处在于系统的时钟由50M提成为100M.运行结果,在调试窗口输出Hello from Nios II!,并且板上的四个LED灯流动显示, ...

  3. CSS 问题集锦

    [1]让DIV中的内容居中 1.文字垂直居中,关键代码:height:100px;line-height:100px(两个值要相等) <div style="margin:0 auto ...

  4. BroadcastReceiver之SD的挂载监听

    首先,新建一个类,继承于BroadcastReceiver,然后去配置Manifest.xml这就不用说了, 注意配置Manifest.xml时候的一些细节 必须加上<data android: ...

  5. iOS- -安装cocopods

    已经不是第一次安装cocoapods了, 但是今天在自己的mac pro 安装cocoapods 出现了 Error installing pods:active support requires R ...

  6. 十天冲刺---Day2

    站立式会议 站立式会议内容总结: git上Issues新增内容: 燃尽图 照片

  7. 基于tiny4412原生uboot修改制作SD启动并烧写到emmc

    最近入手tiny4412的标准板,底板SDK型号为1506.但是因为友善之臂提供的superboot不能进入boot菜单,此时我就不能通过tftp下载内核和通过nfs挂载根文件系统,于是想自己做个ub ...

  8. context:component-scan扫描使用的use-default-filters

    如下方式可以成功扫描到@Controller注解的Bean,不会扫描@Service/@Repository的Bean. <context:component-scan base-package ...

  9. <诗经>的由来

    <人间词话七讲> 第一讲 那是一个把各地的歌谣都编辑在一起的collection. 而且, 它被编辑的时候有一个目的, 在周朝的时候有采诗之官, 他们采集各地的歌谣, 以观民风, 用来给周 ...

  10. mindmup-editabletable-编辑table的使用

    官方网站:http://mindmup.github.io/editable-table/ github下载地址:https://github.com/mindmup/editable-table 我 ...