Codeforces Round #381 (Div. 2) C 思维 D树上差分

来源:互联网 发布:java可以做前端吗 编辑:程序博客网 时间:2024/06/06 03:03

C:

题意:有N个数的序列,接着给出M组(leftright),对于每一组(leftright)为下标对应的序列区间,mex为不在该区间的最小非负整数。这道这样一组N个数的序列,使得M个mex值中的最小值最大。
739A - Alyona and mexObviously, the answer to the problem can not be greater than the minimum length among the lengths of the sub-arrays. Suppose that the minimum length of all the sub-arrays is equal to len. Then the desired array is: 0, 1, 2, 3, ..., len - 1, 0, 1, 2, 3, ... len - 1... . Not hard to make sure that mex of any subarray will be at least len.

D:

题目http://codeforces.com/contest/739/problem/B

题意:一棵根节点为1的树,每个点都有点值a[i],每条边也有权值,dist(v, u)表示从v到u边权和,当u时v的子孙并且dist(v, u)<=a[u]时u就受v控制,输出每个结点能控制的结点数。思路:如果v可以控制u,那么从v到u的路上的所有结点都可以控制u,因为从v到u路上的dist(vi, u)是递减的,可以每次遍历一个点的时候,二分找出根节点到当前点i路径上点,找出dist(j, i)刚好大于a[i]的点,使得ans[j]--,而后遍历当前点i的所有儿子结点k,ans[i] += ans[k]

说是什么“差分”,http://blog.csdn.net/zhayan9qvq/article/details/54999472参考下。

这个别人的代码很6。。 感觉自己很难写出来。。

    #include <bits/stdc++.h>      using namespace std;      #define maxn 200010      #define ll long long int      vector<ll> val[maxn];      vector<int> G[maxn];      vector<pair<ll, int> > que;      ll dis[maxn], a[maxn];      int ans[maxn];      void dfs(int x, int fa){          ans[x] = 1;          ll t = dis[x] - a[x];          int pos = lower_bound(que.begin(), que.end(), make_pair(t, 0))-que.begin();          pos--;          if(pos>=0) ans[que[pos].second]--;          que.push_back(make_pair(dis[x], x));          for(int i = 0;i < G[x].size();i++){              int y = G[x][i];              if(y == fa) continue;              dis[y] = dis[x] + val[x][i];              dfs(y, x);              ans[x] += ans[y];          }          que.pop_back();      }      int main()      {          int n, i;          scanf("%d", &n);          for(i = 1;i <= n;i++) scanf("%I64d", &a[i]);          int v;          ll cost;          for(i = 2;i <= n;i++){              scanf("%d %I64d", &v, &cost);              val[i].push_back(cost);              val[v].push_back(cost);              G[i].push_back(v);              G[v].push_back(i);          }          dfs(1, -1);          for(i = 1;i <= n;i++) printf("%d%c", ans[i]-1, i==n?'\n':' ');      }  

这个代码更好看懂,
参考http://blog.csdn.net/cabinfever/article/details/53325717

#include <cstdio>#include <cmath>#include <cstring>#include <string>#include <cstdlib>#include <algorithm>#include <iostream>using namespace std;const int maxn = 200010;const int lg = 20;int n;long long a[maxn];long long c[maxn];struct edge{    int v,w,next;}e[maxn << 1];long long dep[maxn];int h[maxn],num = 0;int f[maxn][lg+1];int u,v;long long w;void build(int u,int v,int w){    num++;    e[num].v = v;    e[num].w = w;    e[num].next = h[u];    h[u] = num;}void dfs1(int x,int fa){    int v;    f[x][0] = fa;    for(int i = 1; i < lg; i++)        f[x][i] = f[f[x][i-1]][i-1];    int u = x;    for(int i = lg - 1; i >= 0; i--)        while(u > 1 && dep[x] - dep[f[u][i]] <= a[x])            u = f[u][i];    u = max(1,u);    c[f[u][0]]--;    c[f[x][0]]++;    for(int i = h[x]; i; i = e[i].next)    {        v = e[i].v;        if(v != fa)        {            dep[v] = dep[x] + e[i].w;            dfs1(v,x);        }    }}void dfs2(int x,int f){    int v;    for(int i = h[x]; i; i = e[i].next)    {        v = e[i].v;        if(v != f)        {            dfs2(v,x);            c[x] += c[v];        }    }}int main(){    freopen("1.in","r",stdin);    cin >> n;    for(int i = 1; i <= n; i++)        scanf("%I64d",&a[i]);    for(int i = 2; i <= n; i++)    {        scanf("%d%I64d",&v,&w);        build(i,v,w);        build(v,i,w);    }    dfs1(1,0);    dfs2(1,0);    for(int i = 1; i <= n; i++)        printf("%I64d%c",c[i],i == n ? '\n' : ' ');    return 0;}
阅读全文
0 0
原创粉丝点击