fzu 2136 取糖果(线段树)

题目链接:fzu 2136 2136 取糖果

题目大意:略。

解题思路:线段树区间合并。将袋子按照个数排序,每次将最小的放入线段树,如果当前连续的个数超过区间,那么说

明最小值即为最后加入的袋子糖果个数。

#include <cstdio>
#include <cstring>
#include <vector>
#include <algorithm>

using namespace std;

const int maxn = 1e5 + 5;

#define lson(x) ((x)<<1)
#define rson(x) (((x)<<1)|1)
int lc[maxn << 2], rc[maxn << 2], L[maxn << 2], R[maxn << 2], S[maxn << 2];

void pushup(int u) {
    S[u] = max(max(S[lson(u)], S[rson(u)]), R[lson(u)] + L[rson(u)]);
    L[u] = L[lson(u)] + (L[lson(u)] == rc[lson(u)] - lc[lson(u)] + 1 ? L[rson(u)] : 0);
    R[u] = R[rson(u)] + (R[rson(u)] == rc[rson(u)] - lc[rson(u)] + 1 ? R[lson(u)] : 0);
}

void build (int u, int l, int r) {
    lc[u] = l;
    rc[u] = r;
    L[u] = R[u] = S[u] = 0;

    if (l == r)
        return;

    int mid = (l + r) >> 1;
    build(lson(u), l,  mid);
    build(rson(u), mid + 1, r);
    pushup(u);
}

void modify(int u, int x, int w) {
    if (lc[u] == x && x == rc[u]) {
        S[u] = R[u] = L[u] = w ? rc[u] - lc[u] + 1 : 0;
        return;
    }

    int mid = (lc[u] + rc[u]) >> 1;
    if (x <= mid)
        modify(lson(u), x, w);
    else
        modify(rson(u), x, w);
    pushup(u);
}

typedef pair<int, int> pii;
vector<pii> vec;

int main () {
    int cas;
    scanf("%d", &cas);

    while (cas--) {
        int n, x;
        vec.clear();

        scanf("%d", &n);
        for (int i = 1; i <= n; i++) {
            scanf("%d", &x);
            vec.push_back(make_pair(x, i));
        }

        sort(vec.begin(), vec.end());

        build(1, 1, n);
        int mv = 0;
        for (int k = 1; k <= n; k++) {
            while (S[1] < k)
                modify(1, vec[mv++].second, 1);
            printf("%d\n", vec[mv-1].first);
        }
    }
    return 0;
}
时间: 2024-12-28 17:45:25

fzu 2136 取糖果(线段树)的相关文章

fzu 2105 Digits Count 线段树

题目链接:http://acm.fzu.edu.cn/problem.php?pid=2105 题意: 给出一个数组A[0]-A[n-1],每个数最大是16.有4种操作: AND opn L R:L-R区间内的数都AND上opn这个数 OR opn L R:L-R区间内的数都OR上opn这个数 XOR opn L R:L-R区间内的数都XOR上opn这个数 SUM L R:求L-R区间内所有数的和. 0 <= opn <= 16 思路: 可以发现A[i]和opn最大都不超过16,所以可以设4个

FZU2136--取糖果 (线段树+RMQ)

Problem Description 有N个袋子放成一排,每个袋子里有一定数量的糖果,lzs会随机选择连续的几个袋子,然后拿走这些袋子中包含最多糖果的袋子.现问你,在选择x个袋子的情况下,lzs最坏情况下,也就是最少会拿到多少个糖果?对于x取值为1到n都分别输出答案. Input 第一行一个整数T,表示有T组数据. 每组数据先输入一行一个整数N(1<=N<=100000),表示袋子数,接下来一行输入N个正整数,输入的第i个数表示第i个袋子所装的糖果数. Output 每组数据输出n行,第i行

Problem 2136 取糖果---FUOJ (线段树+维护)

http://acm.fzu.edu.cn/problem.php?pid=2136 题目大意: 给你n个袋子每个袋子里都装有糖果,然后呢你可以每次抽取一个连续的一个区间的袋子,然后带走里面最多糖果数目的袋子. 求区间长度从1到n你能带走的糖果数目最坏的情况是多少,也就是求所有区间的最大值的最小值 分析: 如果从小的开始查找他每次只要找到他能覆盖的区间,那么他就是这个区间的最大值,所以我们每次查询这个点就行了 #include<stdio.h> #include<string.h>

[LintCode] Segment Tree Build II 建立线段树之二

The structure of Segment Tree is a binary tree which each node has two attributes startand end denote an segment / interval. start and end are both integers, they should be assigned in following rules: The root's start and end is given bybuild method

ACM: FZU 2105 Digits Count - 位运算的线段树【黑科技福利】

FZU 2105  Digits Count Time Limit:10000MS     Memory Limit:262144KB     64bit IO Format:%I64d & %I64u Practice Description Given N integers A={A[0],A[1],...,A[N-1]}. Here we have some operations: Operation 1: AND opn L R Here opn, L and R are integer

FZU 2105 Digits Count(按位维护线段树)

[题目链接] http://acm.fzu.edu.cn/problem.php?pid=2105 [题目大意] 给出一个序列,数字均小于16,为正数,每次区间操作可以使得 1. [l,r]区间and一个数 2. [l,r]区间or一个数 3. [l,r]区间xor一个数 4. [l,r]区间查询和 操作数均为小于16的非负整数 [题解] 由于操作数很小,因此我们可以按位维护四棵线段树,表示二进制中的第i位, 对于and操作,只有当and的当前位为0时才对区间有影响,效果是将区间全部变为0, 对

Codeforces Round #250 (Div. 1) D. The Child and Sequence 线段树 区间求和+点修改+区间取模

D. The Child and Sequence At the children's day, the child came to Picks's house, and messed his house up. Picks was angry at him. A lot of important things were lost, in particular the favorite sequence of Picks. Fortunately, Picks remembers how to

FZU Problem 2171 防守阵地 II (线段树,区间更新)

 Problem 2171 防守阵地 II Accept: 143    Submit: 565Time Limit: 3000 mSec    Memory Limit : 32768 KB  Problem Description 部队中总共有N个士兵,每个士兵有各自的能力指数Xi,在一次演练中,指挥部确定了M个需要防守的地点,指挥部将选择M个士兵依次进入指定地点进行防守任务,获得的参考指数即为M个士兵的能力之和.随着时间的推移,指挥部将下达Q个指令来替换M个进行防守的士兵们,每个参加完防守

fzu 2171 线段树 lazy标记

http://acm.fzu.edu.cn/problem.php?pid=2171      Problem 2171 防守阵地 II Accept: 73    Submit: 256Time Limit: 3000 mSec    Memory Limit : 32768 KB Problem Description 部队中总共有N个士兵,每个士兵有各自的能力指数Xi,在一次演练中,指挥部确定了M个需要防守的地点,指挥部将选择M个士兵依次进入指定地点进行防守任务,获得的参考指数即为M个士兵