• 2016"百度之星"


    http://acm.hdu.edu.cn/showproblem.php?pid=5692

    题意:给一棵树,点有权值. 操作1:询问从0点出发,经过x点(输入)的路径中,点权和最大的路径的和是多少. 操作2:将x号点的值更新为y.

    思路:已0为根形成一个有根树,经过x点的所有路径的终点都在已x为根的子树中,问题相当于求一颗子树中的所有节点到0点的距离最大值,将题目的点权理解成距离.

    解法:用dfs顺序对0为根的树标号,按照标号作为线段树的序号,那么某一颗子树的点在线段树的区间也是连续的了,这是一个常见的做法,参见线段树专题的树标号.

    然后bfs,dfs都可以,处理出初始每个点作为终点到0点的路径和. 简单的累加. 线段树维护的是以0为起点 x为终点的路径和数组.

    对于查询操作,就是线段树最大值查询.  对于更新操作, 变化量 delta= now - pre ,  如果一个点值变大delta ,那么以该点为根的子树, 每个点的路径和都会增加这么多,线段树区间更新 +delta.

      1 //#define debug
      2 #include<cstdio>
      3 #include<cstdlib>
      4 #include<vector>
      5 #define lrrt int L,int R,int rt
      6 #define iall 1,n,1
      7 #define imid int mid=(L+R)>>1
      8 #define lson L,mid,rt<<1
      9 #define rson mid+1,R,rt<<1|1
     10 using namespace std;
     11 typedef long long LL;
     12 const LL inf=0x3f3f3f3f3f3f3f3fLL;
     13 const int M=1e5+10;
     14 int n,m;
     15 struct E{
     16     int u,v;
     17 }e[M];
     18 struct Q{
     19     int type,x;
     20     LL y;
     21 }q[M];
     22 int a[M];
     23 vector<LL> answer;
     24 vector<int> g[M];
     25 struct N{
     26     int l,r;
     27 }node[M];
     28 LL dist[M];
     29 int Index;
     30 struct T{
     31     LL value,lazy;
     32 }tree[M<<2];
     33 void init(){
     34     for(int i=0;i<n;i++){
     35         g[i].clear();
     36     }
     37     for(int i=0;i<n-1;i++){
     38         int u=e[i].u;
     39         int v=e[i].v;
     40         g[u].push_back(v);
     41         g[v].push_back(u);
     42     }
     43 }
     44 void dfs(int u,int fa){
     45     node[u].l=++Index;
     46     for(int i=0;i<g[u].size();i++){
     47         int v=g[u][i];
     48         if(v==fa) continue;
     49         dfs(v,u);
     50     }
     51     node[u].r=Index;
     52 }
     53 void dfs_for_dist(int u,int fa){
     54     for(int i=0;i<g[u].size();i++){
     55         int v=g[u][i];
     56         if(v==fa) continue;
     57         dist[v]+=dist[u];
     58         dfs_for_dist(v,u);
     59     }
     60 }
     61 void build(lrrt){
     62     tree[rt].value=0;
     63     tree[rt].lazy=0;
     64     if(L==R) return ;
     65     imid;
     66     build(lson);
     67     build(rson);
     68 }
     69 void pushup(int rt){
     70     tree[rt].value=max(tree[rt<<1].value,tree[rt<<1|1].value);
     71 }
     72 void pushdown(int rt){
     73     LL &z=tree[rt].lazy;
     74     if(z!=0){
     75         tree[rt<<1].lazy+=z;
     76         tree[rt<<1|1].lazy+=z;
     77         tree[rt<<1].value+=z;
     78         tree[rt<<1|1].value+=z;
     79         z=0;
     80     }
     81 }
     82 void update(int x,int y,LL z,lrrt){
     83     if(x<=L&&R<=y){
     84         tree[rt].value+=z;
     85         tree[rt].lazy+=z;
     86         return ;
     87     }
     88     imid;
     89     pushdown(rt);
     90     if(mid>=x) update(x,y,z,lson);
     91     if(mid<y)  update(x,y,z,rson);
     92     pushup(rt);
     93 }
     94 LL query(int x,int y,lrrt){
     95     if(x<=L&&R<=y) return tree[rt].value;
     96     imid;
     97     pushdown(rt);
     98     LL big=-inf;
     99     if(mid>=x) big=max(big,query(x,y,lson));
    100     if(mid<y)  big=max(big,query(x,y,rson));
    101     return big;
    102 }
    103 void solve(){
    104     init();
    105     Index=0;
    106     dfs(0,-1);
    107     for(int i=0;i<n;i++){
    108         dist[i]=a[i];
    109     }
    110     dfs_for_dist(0,-1);
    111     build(iall);
    112     for(int i=0;i<n;i++){
    113         #ifdef debug
    114         printf("i=%d  l=%d  r=%d
    ",i,node[i].l,node[i].r);
    115         #endif // debug
    116         update(node[i].l,node[i].l,dist[i],iall);
    117     }
    118     answer.clear();
    119     for(int i=0;i<m;i++){
    120         if(q[i].type){
    121             int u=q[i].x;
    122             answer.push_back(query(node[u].l,node[u].r,iall));
    123         }
    124         else{
    125             int u=q[i].x;
    126             LL d=q[i].y-a[u];
    127             a[u]=q[i].y;
    128             update(node[u].l,node[u].r,d,iall);
    129         }
    130     }
    131 }
    132 int main(){
    133     int t;
    134     while(~scanf("%d",&t)){
    135         int cas=1;
    136         while(t--){
    137             scanf("%d%d",&n,&m);
    138             for(int i=0;i<n-1;i++){
    139                 scanf("%d%d",&e[i].u,&e[i].v);
    140             }
    141             for(int i=0;i<n;i++){
    142                 scanf("%d",&a[i]);
    143             }
    144             for(int i=0;i<m;i++){
    145                 scanf("%d%d",&q[i].type,&q[i].x);
    146                 if(q[i].type==0){
    147                     scanf("%I64d",&q[i].y);
    148                 }
    149             }
    150             solve();
    151             printf("Case #%d:
    ",cas++);
    152             for(int i=0;i<answer.size();i++){
    153                 printf("%I64d
    ",answer[i]);
    154             }
    155         }
    156     }
    157     return 0;
    158 }
    View Code

    http://acm.hdu.edu.cn/showproblem.php?pid=5695

    题意:n个人排队 ,给出m对点,表示u 不希望 v 排在自己前面, 每个人的得分是前面包括自己在内id的最小值。求一个排列,满足要求,且总分最高。

    解法:u-》v建一条有向边 ,拓扑排序的结果就是一个合法的解。要使得总分高,那么当有多个可以排队的情况下,贪心选取id大的先排会使得得分大。

     1 #include<cstdio>
     2 #include<vector>
     3 #include<queue>
     4 using namespace std;
     5 typedef long long LL;
     6 const int M=1e5+10;
     7 int t,n,m;
     8 struct E{
     9     int u,v;
    10 }e[M];
    11 int d[M];
    12 int answer[M];
    13 vector<int> g[M];
    14 priority_queue<int> q;
    15 void init(){
    16     for(int i=1;i<=n;i++){
    17         d[i]=0;
    18         g[i].clear();
    19     }
    20     for(int i=0;i<m;i++){
    21         g[e[i].u].push_back(e[i].v);
    22         d[e[i].v]++;
    23     }
    24 }
    25 LL solve(){
    26     init();
    27     while(!q.empty()) q.pop();
    28     for(int i=1;i<=n;i++){
    29         if(!d[i]){
    30             q.push(i);
    31         }
    32     }
    33     int la=0;
    34     while(!q.empty()){
    35         int u=q.top();
    36         q.pop();
    37         answer[la++]=u;
    38         for(int i=0;i<g[u].size();i++){
    39             int v=g[u][i];
    40             d[v]--;
    41             if(!d[v]){
    42                 q.push(v);
    43             }
    44         }
    45     }
    46     LL sum=0;
    47     int small=n+1;
    48     for(int i=0;i<n;i++){
    49         small=min(small,answer[i]);
    50         sum+=small;
    51     }
    52     return sum;
    53 }
    54 int main(){
    55     while(~scanf("%d",&t)){
    56         while(t--){
    57             scanf("%d%d",&n,&m);
    58             for(int i=0;i<m;i++){
    59                 scanf("%d%d",&e[i].u,&e[i].v);
    60             }
    61             printf("%lld
    ",solve());
    62         }
    63     }
    64     return 0;
    65 }
    View Code

    end

  • 相关阅读:
    Could not load file or assembly Microsoft.SqlServer.management.sdk.sfc version 11.0.0.0
    代码覆盖率 (Code Coverage)从简到繁 (一)
    vscode配置自动格式化eslint 配置模板
    无效的源发行版: 10
    java读取一个文件写入另外一个文件
    notepad++使用正则表达式匹配
    jsp页面返回字符串而非方法执行后取得的数据?
    maven的原始setting.xml文件,自带阿里云镜像,之前配的时候出错,保存一下,注意可以在localRepository处设置存储依赖的地址,大概在49到54行,我的是<localRepository>F:/MavenRepository</localRepository>,F盘要先有这个文件夹
    Java 8 lambda Stream list to Map key 重复 value合并到Collection
    BufferedReader.readLine()读取文件
  • 原文地址:https://www.cnblogs.com/gaolzzxin/p/5515419.html
Copyright © 2020-2023  润新知