BestCoder Round #91

传送门:http://acm.hdu.edu.cn/search.php?field=problem&key=BestCoder+Round+%2391&source=1&searchmode=source

A题:给你n种字母,每种字母有个权值vali,共cnti个,现在让你在里面挑出任意数量的字符,组合成一个字符串,该字符串的权值的计算方式为val1*1+val2*2+……+valn*n,让你输出字符串最大的权值是多少。这题很容易会有一个错误的贪心,就是把val为负的舍去,然后val从小到大选择。事实上负值时可以选的,比如字符1的权值为-1,字符2的权值为2,字符3的权值为3,那么如果我不选字符1,总权值为2*1+3*2=8,小于选了字符1的权值-1*1+2*2+3*3=12,所以这种贪心是错的。正解是先按val对字符排序,很明显,val大的字符如果不选,val小的就一定不会选。也即是,如果字符ch选了,权值比它大的肯定也会选。那假设它选了,总权值就会增加valch+valch+1,valch+2……valn,因此只要判断valch+valch+1,valch+2……valn是不是大于0,就能确定ch到底要不要选了。可以预处理下后缀和,然后直接扫一遍。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <vector>
#include <queue>
#include <string>
#include <stack>
#include <map>
#include <set>
#include <bitset>
#define X first
#define Y second
#define clr(u,v); memset(u,v,sizeof(u));
#define in() freopen("data","r",stdin);
#define out() freopen("ans","w",stdout);
#define Clear(Q); while (!Q.empty()) Q.pop();
#define pb push_back

using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
const int maxn = 1e5 + 10;
const int INF = 0x3f3f3f3f;
pii N[100];
vector <int> V;
int sum[maxn];

int main()
{
    int T;
    scanf("%d", &T);
    while (T--)
    {
        V.clear();
        int n;
        scanf("%d", &n);
        for (int i = 0; i < n; i++)
        {
            scanf("%d%d", &N[i].X, &N[i].Y);
            while (N[i].Y--)
                V.pb(N[i].X);
        }
        sort(V.begin(), V.end());
        sum[V.size()] = 0;
        for (int i = V.size() - 1; i >= 0; i--)
            sum[i] = sum[i+1] + V[i];
        ll ans = 0, k = 1;
        for (int i = 0; i < V.size(); i++)
            if (V[i] >= 0 || V[i] + sum[i+1] >= 0)
            {
                ans += k * V[i];
                k++;
            }
        printf("%I64d\n", ans);
    }
    return 0;
}

B题:有n种植物,每种植物有个适宜温度区间,如果温度适宜,它可以提供ai的研究价值,如果温度大于适宜温度的上限,它可以提供bi的研究价值,如果温度小于适宜温度的下限,它可以提供ci的研究价值。现在让你找到一个温度,使得总研究价值最大,温度可以为任意实数。输出最大总研究价值。先离散化一下温度,然后线段树维护下最大研究价值。注意由于温度是实数,所以离散的时候要,两个数之间要多加一个空位,用于浮点数的统计。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <vector>
#include <queue>
#include <string>
#include <stack>
#include <map>
#include <set>
#include <bitset>
#define X first
#define Y second
#define clr(u,v); memset(u,v,sizeof(u));
#define in() freopen("data","r",stdin);
#define out() freopen("ans","w",stdout);
#define Clear(Q); while (!Q.empty()) Q.pop();
#define pb push_back
#define lson l , m , rt << 1
#define rson m + 1 , r , rt << 1 | 1

using namespace std;
typedef long long LL;
typedef pair<int, int> pii;
const int maxn = 2e5 + 10;
const int inf = 0x3f3f3f3f;
struct node1
{
    int l, r, a, b, c;
} N[maxn];
vector<pii> V;
LL add[maxn<<2];
LL Max[maxn<<2];
void PushUp(int rt)
{
    Max[rt] = max(Max[rt<<1] , Max[rt<<1|1]);
}
void PushDown(int rt, int m)
{
    if (add[rt])
    {
        add[rt<<1] += add[rt];
        add[rt<<1|1] += add[rt];
        Max[rt<<1] += add[rt];
        Max[rt<<1|1] += add[rt];
        add[rt] = 0;
    }
}

void update(int L, int R, int c, int l, int r, int rt)
{
    if (L <= l && r <= R)
    {
        add[rt] += c;
        Max[rt] += c;
        return ;
    }
    PushDown(rt , r - l + 1);
    int m = (l + r) >> 1;
    if (L <= m) update(L , R , c , lson);
    if (m < R) update(L , R , c , rson);
    PushUp(rt);
}
LL query(int L, int R, int l, int r, int rt)
{
    if (L <= l && r <= R)
    {
        return Max[rt];
    }
    PushDown(rt , r - l + 1);
    int m = (l + r) >> 1;
    LL ret = 0;
    if (L <= m) ret = max(ret, query(L , R , lson));
    if (m < R) ret = max(ret, query(L , R , rson));
    return ret;
}

void init()
{
    V.clear();
    clr(add, 0);
    clr(Max, 0);
}

int main()
{
    int T;
    scanf("%d", &T);
    while (T--)
    {
        init();
        V.pb(make_pair(0,-1));
        int n;
        scanf("%d", &n);
        for (int i = 0; i < n; i++)
        {
            scanf("%d%d%d%d%d", &N[i].l, &N[i].r, &N[i].a, &N[i].b, &N[i].c);
            V.pb(make_pair(2 * N[i].l , i));
            V.pb(make_pair(2 * N[i].r , i));
            V.pb(make_pair(2 * N[i].l + 1, -1));
            V.pb(make_pair(2 * N[i].r + 1, -1));
            N[i].l = N[i].r = -1;
        }
        int pos = 1;
        sort(V.begin(), V.end());
        for (int i = 0; i < V.size(); i++)
        {
            if (V[i].Y == -1)
            {
                pos++;
                continue;
            }
            if (N[V[i].Y].l == -1)
                N[V[i].Y].l = pos;
            else N[V[i].Y].r = pos;
            if (i != V.size() - 1 && V[i].X == V[i+1].X) continue;
            pos++;
        }
        pos--;
        for (int i = 0; i < n; i++)
        {
            if (N[i].l - 1 >= 1) update(1, N[i].l - 1, N[i].c, 1, pos, 1);
            update(N[i].l, N[i].r, N[i].a, 1, pos, 1);
            if (N[i].r + 1 <= pos) update(N[i].r + 1, pos, N[i].b, 1, pos, 1);
        }
        printf("%I64d\n", query(1, pos, 1, pos, 1));
    }
    return 0;
}

剩下两题不会了= =,这场能升分得益于A题的错误贪心发现得早。。没造成太多罚时损失,遗憾是手速太慢没hack到人。B题知道做法,但是调线段树调了半天,还没注意到可以是实数,样例一直调不过,决定去刷下线段树专题,,补补线段树。

2017-01-23 22:09:00

时间: 2024-10-20 02:17:34

BestCoder Round #91的相关文章

BestCoder Round #91 1002 Lotus and Horticulture

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6012 题意: 这几天Lotus对培养盆栽很感兴趣,于是她想搭建一个温室来满足她的研究欲望. Lotus将所有的nn株盆栽都放在新建的温室里,所以所有盆栽都处于完全相同的环境中. 每一株盆栽都有一个最佳生长温度区间[l,r][l,r],在这个范围的温度下生长会生长得最好,但是不一定会提供最佳的研究价值(Lotus认为研究发育不良的盆栽也是很有研究价值的). Lotus进行了若干次试验,发现若第ii株盆

从lca到树链剖分 bestcoder round#45 1003

bestcoder round#45 1003 题,给定两个点,要我们求这两个点的树上路径所经过的点的权值是否出现过奇数次.如果是一般人,那么就是用lca求树上路径,然后判断是否出现过奇数次(用异或),高手就不这么做了,直接树链剖分.为什么不能用lca,因为如果有树退化成链,那么每次询问的复杂度是O(n), 那么q次询问的时间复杂度是O(qn) 什么是树链剖分呢? 就是把树的边分成轻链和重链 http://blogsina.com.cn/s/blog_6974c8b20100zc61.htmlh

hdu 5195 DZY Loves Topological Sorting BestCoder Round #35 1002 [ 拓扑排序 + 优先队列 || 线段树 ]

传送门 DZY Loves Topological Sorting Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)Total Submission(s): 221    Accepted Submission(s): 52 Problem Description A topological sort or topological ordering of a directed

hdu 5066 Harry And Physical Teacher(Bestcoder Round #14)

Harry And Physical Teacher Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 91    Accepted Submission(s): 68 Problem Description As we all know, Harry Porter learns magic at Hogwarts School. How

BestCoder Round #29 1003 (hdu 5172) GTY&#39;s gay friends [线段树 判不同 预处理 好题]

传送门 GTY's gay friends Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 264    Accepted Submission(s): 57 Problem Description GTY has n gay friends. To manage them conveniently, every morning he o

BestCoder Round #1 1001 &amp;&amp; 1002 hdu 4857 4858

hdu 4857 逃生 第一题是拓扑排序,不是按照字典序最小输出,而是要使较小的数排在最前面..赛后弄了好久,才比较明白,我一直以为 反向建图,i从1到n,开始深搜dfs( i ),对i点的边,由小到大继续搜一下,同时标记搜过的数,搜过之后就不再搜,搜到底之后ans[cnt++] = u;这样顺序输出就是答案,后来经过超哥指点,才明白深搜贪心是错的.只有 反向建图,用优先队列把较大的数尽量排在前面,然后反序输出才是正解.. 1 #include<iostream> 2 #include<

BestCoder Round #65 (ZYB&#39;s Game)

ZYB's Game Accepts: 672 Submissions: 1207 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others) Problem Description ZYBZYBZYB played a game named NumberBombNumber BombNumberBomb with his classmates in hiking:a host keeps a

hdu5418 BestCoder Round #52 (div.2) Victor and World ( floyd+状压dp)

Problem Description After trying hard for many years, Victor has finally received a pilot license. To have a celebration, he intends to buy himself an airplane and fly around the world. There are n countries on the earth, which are numbered from 1 to

hdu 5163 Taking Bus (BestCoder Round #27)

Taking Bus                                                               Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 501    Accepted Submission(s): 203 Problem Description Bestland has a v