zoukankan      html  css  js  c++  java
  • bzoj 3697: 采药人的路径

    点分治自己水的题(以为这辈子也做不出点分治了23333)(此题坑爹,需要LL)

    考虑这道题,需要求出的是01数量相同搞的路径,而且,需要有一个休息点(这个有意思)

    我们来分析这个休息点,我们设一条路径满足要求,那么休息点也就从起点到休息点01相同。那么来处理休息点。

    开始打标记。标记从根节点走过的一个路径和d,现在的点x,那么只需要的是在根节点到x的路径上再有一个点的距离为x即可,那么那个点就可以作为休息点。

    所以,我们设t[?+N][0/1](设0的路径权值为-1,1的为1,所以?需要加个常数N)为距离根节点距离为?,1表示中间有休息点,0表示没有休息点。那么答案就是t[N-?][1/0]

    如果中间有休息点,就加t[N-?][0]+t[N-?][1],如果没有,那么就只能加t[N-?][1],统计答案和bzoj2599的方法相似(下一篇会有)(貌似变成心机婊了2333)

      1 #include<bits/stdc++.h>
      2 #define N 100005
      3 #define M 10000005
      4 #define LL long long
      5 #define inf 0x3f3f3f3f
      6 using namespace std;
      7 inline int ra()
      8 {
      9     int x=0,f=1; char ch=getchar();
     10     while (ch<'0' || ch>'9') {if (ch=='-') f=-1; ch=getchar();}
     11     while (ch>='0' && ch<='9') {x=x*10+ch-'0'; ch=getchar();}
     12     return x*f;
     13 }
     14 struct node{
     15     int to,next,v;
     16 }e[N<<1];
     17 int size[N],f[N],d[N],n,head[N],cnt,sum,root;
     18 LL ans,t[N<<1][3];
     19 bool vis[N]; int inq[N<<1];
     20 void insert(int x, int y, int v)
     21 {
     22     e[++cnt].next=head[x]; e[cnt].to=y; e[cnt].v=v; head[x]=cnt;
     23 }
     24 void getroot(int x, int fa)
     25 {
     26     size[x]=1; f[x]=0;
     27     for (int i=head[x];i;i=e[i].next)
     28     {
     29         if (vis[e[i].to] || e[i].to==fa) continue;
     30         getroot(e[i].to,x);
     31         size[x]+=size[e[i].to];
     32         f[x]=max(f[x],size[e[i].to]);
     33     }
     34     f[x]=max(f[x],sum-size[x]);
     35     if (f[x]<f[root]) root=x;
     36 }
     37 void cal(int x, int fa)
     38 {
     39     if (inq[d[x]+N]) 
     40         ans+=t[N-d[x]][1]+t[N-d[x]][0];
     41     else ans+=t[N-d[x]][1];
     42     inq[d[x]+N]++;
     43     for (int i=head[x];i;i=e[i].next)
     44     {
     45         if (e[i].to==fa || vis[e[i].to]) continue;
     46         d[e[i].to]=d[x]+e[i].v;
     47         cal(e[i].to,x);
     48     }
     49     inq[d[x]+N]--;
     50 }
     51 void add(int x, int fa, int flag)
     52 {
     53     if (flag) {
     54         if (inq[d[x]+N]) t[d[x]+N][1]++;
     55             else t[d[x]+N][0]++;
     56     }
     57     else t[d[x]+N][1]=t[d[x]+N][0]=0;
     58     inq[d[x]+N]++;
     59     for (int i=head[x];i;i=e[i].next)
     60         if (!vis[e[i].to] && fa!=e[i].to)
     61             add(e[i].to,x,flag);
     62     inq[d[x]+N]--;
     63 }
     64 void work(int x)
     65 {
     66     vis[x]=1; t[N][0]=1;
     67     for (int i=head[x];i;i=e[i].next)
     68     {
     69         if (vis[e[i].to]) continue;
     70         d[e[i].to]=e[i].v; 
     71         cal(e[i].to,0);
     72         inq[N]=1;
     73         add(e[i].to,0,1);
     74         inq[N]=0;
     75     }
     76     for (int i=head[x];i;i=e[i].next)
     77         if (!vis[e[i].to]) add(e[i].to,0,0);
     78     for (int i=head[x];i;i=e[i].next)
     79     {
     80         if (vis[e[i].to]) continue;
     81         root=0; sum=size[e[i].to];
     82         getroot(e[i].to,0);
     83         work(root);
     84     }
     85 }
     86 int main()
     87 {
     88     n=ra();
     89     for (int i=1; i<n; i++)
     90     {
     91         int x=ra(),y=ra(),v=ra();
     92         if (v==0) v=-1;
     93         insert(x,y,v); insert(y,x,v);
     94     }
     95     sum=f[0]=n;
     96     getroot(1,0);
     97     work(root);
     98     cout<<ans;
     99     return 0;
    100 }
  • 相关阅读:
    频率组件
    Django-admin组件
    Python全栈开发课堂笔记_day03
    python全栈开发day02
    python全栈开发day01
    正确认知自己,做真实的自己
    翻出大学时期收集的文章来看看
    mybatis中的#{}和${}
    Parameter index out of range (2 > number of parameters, which is 1)
    中间件
  • 原文地址:https://www.cnblogs.com/ccd2333/p/6418912.html
Copyright © 2011-2022 走看看