zoukankan      html  css  js  c++  java
  • r8

    1 今天干的俄罗斯的一场多校,被虐哭啊,就做出两题。
    2
    3
    4
    5
    6
    7


    8 题目讲得是给你一串数字,然后给你i,p,表示从第i开始,对这串数离散话,并且离散化后的字典序要最小,然后输出原来下标为i+p的离散化后的值
    9 是多少。
    10 假设i+p这个位置上的数为a。
    11 如果在(i,i+p)这个范围内没有a,并且这个区间内没有重复的数,那么答案就是p
    12 那么按照这个思路走,其实我们只要知道距离i位置最近的a的下标为r,那么其实我们只要知道(i,r)这个区间中有多少个不同的数n,那么答案就是
    13 n+1。
    14 因为数据比较大,所已对于每次的询问的复杂度必须做到O(1) , O(log(n)) 或 O(sqrt(n)).
    15 就这道题而言用线段数O(logn)是可以的,进爷用默队算法O(sqrt(n))也做到了,我也想到了一种O(logn)的算法,蛋奶和,写不出来:
    16 首先我们用RMQ预处理出每段区间的最大值,然后在询问的过程中我们便能用O(1)知道要求的区间的最大值R了,然后呢,用线段数去求R在这段区间按里是
    17 第k大,然后k就是答案。(大家都觉得蛮有道理,但都懒得敲。。。)
    18
    19
    20


    22 题目告诉你n个城市的人口p[n],他们是构成了一棵树,在告诉你n-1条的路w[n],从一个城市v到u所需要的代价为p[v]*(u到v的距离).
    23 然后我们要在n个城市里选出一个当首都,使其他所有城市到他的代价和最小。
    24 欣爷一看就说是树形dp,然后就a掉了。
    25 我们可以以编号为1的城市为根开始搜索,用o(n)的复杂度,得到一棵树,用d[u]来保存u这个节点的所有子节点到它的代价和,sum[u]来保存每棵子数
    26 中总人口量。
    27 这样一遍下来,其实我们就知道了以1号城市为首都的待价d[1],我们设dp[n]为n号城市当首都的代价,显然dp[1] = d[1] ;
    28 然后如果你思路足够清晰的话可以得到这样一个递推式,设u为v的母亲,n个城市的总人数为all ,
    29 那么dp[v] = d[v] +(all - sum[v])*(u到v的长度)+ dp[u] - d[v] - sum[v]*(u到v的长度) ;

     1 #include<stdio.h>
     2 #include<vector>
     3 #include<set>
     4 #include<string.h>
     5 #include<algorithm>
     6 using namespace std;
     7 typedef long long ll ;
     8 const int M = 100000 + 20 ;
     9 int n , city[M] ;
    10 vector<pair<int , int> > g[M] ;
    11 ll d[M] , dp[M];
    12 bool vis[M] ;
    13 ll sum[M] ;
    14 ll all ;
    15 ll minn , id ;
    16 
    17 void tree (int u) {
    18     for (int i = 0 ; i < g[u].size () ; i ++) {
    19         int v = g[u][i].first ;
    20         if (vis[v]) continue ;
    21         vis[v] = 1 ;
    22         dp[v] = (all - sum[v] ) * g[u][i].second + dp[u] - sum[v] * g[u][i].second ;
    23         if (dp[v] < minn) {
    24             minn = dp[v] ;
    25             id = v ;
    26         }
    27         tree (v) ;
    28     }
    29 }
    30 
    31 void dfs (int u) {
    32     for (int i = 0 ; i < g[u].size () ; i ++) {
    33         int v = g[u][i].first ;
    34         if (vis[v] ) continue ;
    35         vis[v] = 1 ;
    36         dfs (v) ;
    37         d[u] += sum[v] * g[u][i].second + d[v] ;
    38         sum[u] += sum[v] ;
    39     }
    40 }
    41         
    42 
    43 int main () {
    44     freopen ("house.in" , "r" , stdin) ;
    45     freopen ("house.out" , "w" , stdout) ;
    46     scanf ("%d" , &n ) ;
    47     for (int i = 0 ; i < n ; i ++) {
    48                scanf ("%d" , &city[i + 1] ) ;
    49         sum[i + 1] = city[i + 1] ;
    50         all += sum[i + 1] ;
    51     }
    52     for (int i = 0 ; i < n - 1 ; i ++) {
    53         int u , v , w ;
    54         scanf ("%d%d%d" , &u , &v , &w) ;
    55         g[u].push_back (make_pair (v , w) ) ;
    56         g[v].push_back (make_pair (u , w) ) ;
    57     }
    58     //printf ("g[0].size = %d
    " , g[0].size () ) ;
    59     vis[1] = 1 ;
    60     dfs ( 1 ) ;
    61     dp[1] = d[1] ;
    62     minn = d[1] ;
    63     //for (int i = 1 ; i <= n ; i ++) printf ("d[%d] = %d , sum[%d] = %d
    " , i , d[i] , i , sum[i] ) ;
    64     //printf ("d[0] = %d
    " , d[0] ) ;
    65     memset (vis , 0 , sizeof(vis)) ;
    66     vis[1] = 1 ;
    67     id = 1 ;
    68     tree ( 1 ) ;
    69     printf ("%I64d %I64d
    " , id , minn ) ;
    70     return 0 ;
    71 }
    View Code


    30

  • 相关阅读:
    form表单生成的简单理解
    drupal里面的ajax最粗浅的理解-流程
    #array_parents #parents的区别
    hook_schema 小总结
    多语言的sitemap xml
    做百度竞价的步骤 不断总结
    为什么要baidu/Google问题 尽量少在群里问问题
    JavaScript Window对象
    JavaScript 3种内置对象
    图片轮播
  • 原文地址:https://www.cnblogs.com/get-an-AC-everyday/p/4644252.html
Copyright © 2011-2022 走看看