zoukankan      html  css  js  c++  java
  • 2019牛客国庆集训派对day3 买一送一

    题目链接:

    题意:有n个点,n-1条单向边,每个点都销售一类商品

    问从点1开始走,买第一样商品类型为x,买第二样商品类型为y,问不同有序对<x,y>的数量

    解法:

    col[i]表示这个点的商品类型

    last[col[i]]表示从1到点i过程中,点i的商品类型上次出现的时候的点的父亲

    vis[col[i]]表示从1到点i过程中,点i的商品类型经过次数

    num[i]表示从1到点i过程中不同商品类型数量和

    每次扫到新的点v时,(u为v的父亲) num[u] - num[last[col[v]]]就是需要更新的对数

    #include <bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const int M = 1e5 + 10;
    const int mod = 1e9 + 7;
    int num[M], vis[M], anss[M], ans, cnt, col[M], head[M], last[M];
    struct node{
        int next, to;
    }edge[M];
    void add_edge(int u, int v) {
        edge[++cnt].next = head[u];
        edge[cnt].to = v;
        head[u] = cnt;
    }
    void dfs(int u, int sum, int ans) {
        for(int i = head[u]; i; i = edge[i].next) {
            int v = edge[i].to;
            int t = 0;
            int lastt = last[col[v]];
            vis[col[v]]++;
            if(vis[col[v]] == 1) num[v] = num[u] + 1;
            else num[v] = num[u];
            t = num[u] - num[last[col[v]]];
            last[col[v]] = u;
            //printf("%d %d %d
    ", v, col[v], last[col[v]]);
            anss[v] = ans + t;
            if(vis[col[v]] == 1) dfs(v, sum + 1, ans + t);
            else dfs(v, sum + 1, ans + t);
            vis[col[v]]--;
            last[col[v]] = lastt;
        }
    }
    int main(){
        int n;
        while(~scanf("%d", &n)){
            cnt = 0;
            memset(head, 0, sizeof(head));
            for(int i = 1; i <= n; i++) num[i] = 0, last[i] = 0, vis[i] = 0, anss[i] = 0;
            for(int i = 2; i <= n; i++) {
                int u;
                scanf("%d", &u);
                add_edge(u, i);
            }
            for(int i = 1; i <= n; i++)
                scanf("%d", &col[i]);
            vis[col[1]]++;
            num[1] = 1;
            dfs(1, 1, 0);
    //        for(int i = 1; i <= n; i++) {
    //            printf("%d ", num[i]);
    //        }
    //        printf("
    ");
            for(int i = 2; i <= n; i++) {
                printf("%d
    ", anss[i]);
            }
        }
        return 0;
    }
    /*
    3
    1 2
    1 2 3
    3
    1 1
    1 2 3
    4
    1 2 3
    1 3 2 3
    7
    1 1 3 2 4 2
    3 3 3 4 5 3 3
    7
    1 1 3 2 4 2
    2 3 3 4 5 3 3
    */
    View Code
  • 相关阅读:
    2007417 13:01:00 运行时数据结构
    2008515 1:38:00 为受灾的人们祈福,祭那些在地震中离开的人
    200732 19:00:00 一段设置8253芯片的程序
    从实模式到保护模式
    200739 18:01:00 linux界的元老
    2007311 19:11:00 cpu执行第一条指令时情形
    20061127 19:54:00 在你心中有这样的一个人吗? (转)
    linux0.11内存管理——try_to_share()
    2007413 20:46:00 linux0.11之copy_page_tables()函数见解
    POJ1258AgriNet
  • 原文地址:https://www.cnblogs.com/linglinga/p/12077145.html
Copyright © 2011-2022 走看看