• bzoj5457


    城市

     HYSBZ - 5457 

    有n座城市,m个民族。这些城市之间由n-1条道路连接形成了以城市1为根的有根树。每个城市都是某一民族的聚居
    地,Master知道第i个城市的民族是A_i,人数是B_i。为了维护稳定,Master需要知道某个区域内人数最多的民族
    。他向你提出n个询问,其中第i个询问是:求以i为根的子树内,人数最多的民族有是哪个,这个民族有多少人。
    如果子树内人数最多的民族有多个,输出其中编号最小的民族。
     
     
    Input
    共有2*n行。
    第一行有两个整数n, m。
    接下来n-1行,每行有两个整数u, v,表示一条连接u和v的道路。
    接下来n行,第i行有两个整数A_i, B_i。
    n<=400000,m<=n,1<=A_i<=m,0<=B_i<=1000。
     
     
    Output
    共有n行。
    第i行两个整数x, y,分别表示以i为根的子树中人数最多的民族和它的人数。
     
     
    Sample Input
    8 6 1 2 1 3 2 4 4 5 3 6 5 7 1 8 2 8 2 5 1 1 3 1 6 7 5 6 1 10 4 6

    Sample Output

    2 13 1 10 5 6 1 10 1 10 5 6 1 10 4 6

    sol:非常模板的线段树合并

    #include <bits/stdc++.h>
    using namespace std;
    typedef int ll;
    inline ll read()
    {
        ll s=0;
        bool f=0;
        char ch=' ';
        while(!isdigit(ch))
        {
            f|=(ch=='-'); ch=getchar();
        }
        while(isdigit(ch))
        {
            s=(s<<3)+(s<<1)+(ch^48); ch=getchar();
        }
        return (f)?(-s):(s);
    }
    #define R(x) x=read()
    inline void write(ll x)
    {
        if(x<0)
        {
            putchar('-'); x=-x;
        }
        if(x<10)
        {
            putchar(x+'0'); return;
        }
        write(x/10);
        putchar((x%10)+'0');
        return;
    }
    #define W(x) write(x),putchar(' ')
    #define Wl(x) write(x),putchar('
    ')
    const int N=400005;
    #define Mp make_pair
    #define pii pair<int,int>
    int n,m,A[N],B[N];
    int rt[N],cnt=0;
    vector<int>E[N];
    pii Ans[N];
    inline void Link(int x,int y){E[x].push_back(y); E[y].push_back(x);}
    struct Node
    {
        int ls,rs;
        pii mx;
    }T[N*25];
    inline pii pmax(pii a,pii b)
    {
        return ((a.first>b.first)||(a.first==b.first&&a.second<b.second))?a:b;
    }
    inline void PushUp(int x)
    {
        T[x].mx=pmax(T[T[x].ls].mx,T[T[x].rs].mx);
    }
    inline void Insert(int &x,int l,int r,int id,int num)
    {
        if(!x) x=++cnt;
        if(l==r) {T[x].mx=Mp(num,id); return;}
        int mid=(l+r)>>1;
        if(id<=mid) Insert(T[x].ls,l,mid,id,num);
        else Insert(T[x].rs,mid+1,r,id,num);
        PushUp(x);
    }
    inline int Merg(int x,int y,int l,int r)
    {
        if(x*y==0) return x+y;
        if(l==r) {T[x].mx.first+=T[y].mx.first; return x;}
        int mid=(l+r)>>1;
        T[x].ls=Merg(T[x].ls,T[y].ls,l,mid);
        T[x].rs=Merg(T[x].rs,T[y].rs,mid+1,r);
        PushUp(x);
        return x;
    }
    inline void dfs(int x,int fa)
    {
        int i;
        for(i=0;i<E[x].size();i++) 
        {
            int to=E[x][i]; if(to==fa) continue;
            dfs(to,x); rt[x]=Merg(rt[x],rt[to],1,m);
        }
        Ans[x]=T[rt[x]].mx;
    }
    int main()
    {
    //    freopen("5457.in","r",stdin);
        int i,x,y;
        R(n); R(m);
        for(i=1;i<n;i++)
        {
            R(x); R(y); Link(x,y);
        }
        for(i=1;i<=n;i++)
        {
            R(A[i]); R(B[i]); Insert(rt[i],1,m,A[i],B[i]);
        }
        dfs(1,0);
        for(i=1;i<=n;i++) W(Ans[i].second),Wl(Ans[i].first);
        return 0;
    }
    /*
    input
    8 6
    1 2
    1 3
    2 4
    4 5
    3 6
    5 7
    1 8
    2 8
    2 5
    1 1
    3 1
    6 7
    5 6
    1 10
    4 6
    output
    2 13
    1 10
    5 6
    1 10
    1 10
    5 6
    1 10
    4 6
    */
    View Code
  • 相关阅读:
    中位数
    two-strings-are-anagrams&&compare-strings&&longest-words
    第三次作业-------结对编程
    Git的基本使用方法和安装&心得体会(使用git命令行)
    第二次作业-----------结对项目之需求分析与原型设计
    使用Git进行代码管理心得------------个人练习
    Android开发环境的发展演变
    软件工程的实践项目的自我目标
    QT实现2048
    poj3723 Conscription
  • 原文地址:https://www.cnblogs.com/gaojunonly1/p/11173521.html
Copyright © 2020-2023  润新知