zoukankan      html  css  js  c++  java
  • 【BZOJ】【3697】采药人的路径&【3127】【USACO2013 Open】Yin and Yang

    点分治


      Orz hzwer

      倒是比较好想到点分治……然而在方案统计这里,我犯了两个错误……

      1.我比较傻逼的想的是:通过儿子来更新父亲,也就是统计以x为根的子树中xxxx的路径有多少条……这样转移。

      然而这实在是太傻逼了,黄学长教做人:从父亲来更新儿子,走到一个节点直接更新路径的统计数,反正我们要的是【经过root的xx路径的数量】

      所以可以一遍dfs直接搞出来……

      2.统计方案的方式也想错了……我只考虑了以root作为中转站的路径,然而经过root的路径中,并不只有这种路径是合法的……中转站在途中某个点的也可以QwQ

      另外感觉黄学长记录[-d,d]的姿势很神啊……直接数组开大一倍,然后转成[n-d,n+d]……

      其他的……套模板呗- -

      1 //BZOJ 3697
      2 #include<cstdio>
      3 #include<cstring>
      4 #include<cstdlib>
      5 #include<iostream>
      6 #include<algorithm>
      7 #define rep(i,n) for(int i=0;i<n;++i)
      8 #define F(i,j,n) for(int i=j;i<=n;++i)
      9 #define D(i,j,n) for(int i=j;i>=n;--i)
     10 #define pb push_back
     11 using namespace std;
     12 typedef long long LL;
     13 inline int getint(){
     14     int r=1,v=0; char ch=getchar();
     15     for(;!isdigit(ch);ch=getchar()) if (ch=='-') r=-1;
     16     for(; isdigit(ch);ch=getchar()) v=v*10-'0'+ch;
     17     return r*v;
     18 }
     19 const int N=1e5+10;
     20 /*******************template********************/
     21 
     22 int to[N<<1],nxt[N<<1],head[N],cnt,v[N<<1];
     23 void add(int x,int y,int z){
     24     to[++cnt]=y; nxt[cnt]=head[x]; head[x]=cnt; v[cnt]=z;
     25     to[++cnt]=x; nxt[cnt]=head[y]; head[y]=cnt; v[cnt]=z;
     26 }
     27 
     28 int n,rt,s[N],h[N],size,dep[N],mxdeep;
     29 LL ans,g[N*2][2],f[N*2][2];
     30 int t[N<<1],dis[N];
     31 bool vis[N];
     32 
     33 inline void getroot(int x,int fa){
     34     s[x]=1; h[x]=0;
     35     for(int i=head[x];i;i=nxt[i])
     36         if (to[i]!=fa && !vis[to[i]]){
     37             getroot(to[i],x);
     38             s[x]+=s[to[i]];
     39             h[x]=max(h[x],s[to[i]]);
     40         }
     41     h[x]=max(h[x],size-s[x]);
     42     if (h[x]<h[rt]) rt=x;
     43 }
     44 
     45 inline void dfs(int x,int fa){
     46     mxdeep=max(mxdeep,dep[x]);
     47     if (t[dis[x]]) g[dis[x]][1]++;
     48     else g[dis[x]][0]++;
     49     t[dis[x]]++;
     50     for(int i=head[x];i;i=nxt[i])
     51         if (!vis[to[i]] && to[i]!=fa){
     52             dep[to[i]]=dep[x]+1;
     53             dis[to[i]]=dis[x]+v[i];
     54             dfs(to[i],x);
     55         }
     56     t[dis[x]]--;
     57 }
     58 inline void getans(int x){
     59     int mx=0;
     60     vis[x]=1; f[n][0]=1;
     61     for(int i=head[x];i;i=nxt[i])
     62         if (!vis[to[i]]){
     63             dis[to[i]]=n+v[i];
     64             dep[to[i]]=1;
     65             mxdeep=1;
     66             dfs(to[i],x); mx=max(mx,mxdeep);
     67             ans+=(f[n][0]-1)*g[n][0];
     68             F(j,-mxdeep,mxdeep)
     69                 ans+=f[n-j][1]*g[n+j][1]+f[n-j][0]*g[n+j][1]+f[n-j][1]*g[n+j][0];
     70             //f[n][0]+1的原因是要将x作为起点or终点的合法路径(g[n][1])统计进来
     71             F(j,n-mxdeep,n+mxdeep)
     72                 f[j][0]+=g[j][0],
     73                 f[j][1]+=g[j][1],
     74                 g[j][0]=g[j][1]=0;
     75         }
     76     F(i,n-mx,n+mx) f[i][0]=f[i][1]=0;
     77     //统计答案↑
     78     for(int i=head[x];i;i=nxt[i])
     79         if (!vis[to[i]]){
     80             rt=0; size=s[to[i]];
     81             getroot(to[i],x);
     82             getans(rt);
     83         }
     84     //继续分治↑
     85 }
     86 int main(){
     87 #ifndef ONLINE_JUDGE
     88     freopen("3697.in","r",stdin);
     89     freopen("3697.out","w",stdout);
     90 #endif
     91     n=getint();
     92     F(i,2,n){
     93         int x=getint(),y=getint(),z=getint();
     94         if (!z) z--;
     95         add(x,y,z);
     96     }
     97     size=n; h[rt=0]=n+1;
     98     getroot(1,0);
     99     getans(rt);
    100     printf("%lld
    ",ans);
    101     return 0;
    102 }
    View Code

    3697: 采药人的路径

    Time Limit: 10 Sec  Memory Limit: 128 MB
    Submit: 252  Solved: 93
    [Submit][Status][Discuss]

    Description

    采药人的药田是一个树状结构,每条路径上都种植着同种药材。
    采药人以自己对药材独到的见解,对每种药材进行了分类。大致分为两类,一种是阴性的,一种是阳性的。
    采药人每天都要进行采药活动。他选择的路径是很有讲究的,他认为阴阳平衡是很重要的,所以他走的一定是两种药材数目相等的路径。采药工作是很辛苦的,所以 他希望他选出的路径中有一个可以作为休息站的节点(不包括起点和终点),满足起点到休息站和休息站到终点的路径也是阴阳平衡的。他想知道他一共可以选择多 少种不同的路径。

    Input

    第1行包含一个整数N。
    接下来N-1行,每行包含三个整数a_i、b_i和t_i,表示这条路上药材的类型。

    Output

    输出符合采药人要求的路径数目。

    Sample Input

    7
    1 2 0
    3 1 1
    2 4 0
    5 2 0
    6 3 1
    5 7 1

    Sample Output

    1

    HINT

    对于100%的数据,N ≤ 100,000。

    Source

    [Submit][Status][Discuss]
  • 相关阅读:
    阅读笔记 The Impact of Imbalanced Training Data for Convolutional Neural Networks [DegreeProject2015] 数据分析型
    web网站——apache和nginx对比02
    web网站——理论01
    云计算openstack——云计算、大数据、人工智能(16)
    yum管理——ningx部署私有repo源(4)
    zabbix-web监控
    zabbix-自定义监控
    zabbix-邮件报警
    zabbix-自动发现并监控
    web网站——nginx,LNMP部署03
  • 原文地址:https://www.cnblogs.com/Tunix/p/4582763.html
Copyright © 2011-2022 走看看