CF558E A Simple Task

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了CF558E A Simple Task相关的知识,希望对你有一定的参考价值。

鏍囩锛?a href='http://www.mamicode.com/so/1/using' title='using'>using   鏉冨€肩嚎娈垫爲   淇敼   cpp   鏌ヨ   rev   out   瀛楁瘝   switch   

棰樼洰澶ф剰

銆€銆€缁欏畾涓€涓暱搴︿笉瓒呰繃10^5鐨勫瓧绗︿覆锛堝皬鍐欒嫳鏂囧瓧姣嶏級锛屽拰涓嶈秴杩?000涓搷浣溿€傛瘡涓搷浣?L R K 琛ㄧず缁欏尯闂碵L,R]鐨勫瓧绗︿覆鎺掑簭锛孠=1涓哄崌搴忥紝K=0涓洪檷搴忋€傛渶鍚庤緭鍑烘渶缁堢殑瀛楃涓层€?/p>

棰樿В

銆€銆€鎴戜滑鍋氳繃luogu2828锛岄偅閲屾垜浠棤娉曞涓€娈垫暟瀛楀簭鍒楄繘琛屽叿浣撴帓搴忥紝閭d箞杩欓亾棰樻垜浠氨瑕佽€冭檻鍏剁嫭鏈夌殑鐗圭偣銆傚瓧姣嶅彧鏈?6涓紒鎵€浠ユ垜浠姣忎釜瀛楁瘝缁存姢涓€涓猭ey鍊间负涓嬫爣锛屽€间负鍦ㄤ笅鏍囪寖鍥村唴璇ュ瓧姣嶅嚭鐜版鏁扮殑鏉冨€肩嚎娈垫爲鍗冲彲锛屼慨鏀规煡璇㈤兘寰堟柟渚裤€?/p>

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;

const int MAX_N = 100010, MAX_ALPHA = 30;
int N;
int OrgData[MAX_N];
int ValPosCnt[MAX_ALPHA][MAX_N];

struct RangeTree
{
private:
    static const int MAX_NODE = MAX_N * 4;
    int Sum[MAX_NODE], Cover[MAX_NODE];
    
    void PushDown(int cur, int l, int r)
    {
        if(Cover[cur] != -1)
        {
            Cover[cur * 2] = Cover[cur * 2 + 1] = Cover[cur];
            int mid = (l + r) / 2;
            Sum[cur * 2] = (mid - l + 1) * Cover[cur];
            Sum[cur * 2 + 1] = (r - mid) * Cover[cur];
            Cover[cur] = -1;
        }
    }
    
    void PullUp(int cur)
    {
        Sum[cur] = Sum[cur * 2] + Sum[cur * 2 + 1];
    }
    
    void Init(int cur, int l, int r, int *a)
    {
        if(l == r)
        {
            Sum[cur] = a[l];
            return;
        }
        int mid = (l + r) / 2;
        Init(cur * 2, l, mid, a);
        Init(cur * 2 + 1, mid + 1, r, a);
        PullUp(cur);
    }
    
    int Query_Update(int cur, int curL, int curR, int askL, int askR, int cover)
    {
        if(askL <= curL && curR <= askR)
        {
            int ans = Sum[cur];
            Sum[cur] = (curR - curL + 1) * cover;
            Cover[cur] = cover;
            return ans;
        }
        PushDown(cur, curL, curR);
        int mid = (curL + curR) / 2, ans = 0;
        if(askL <= mid)
            ans += Query_Update(cur * 2, curL, mid, askL, askR, cover);
        if (askR > mid)
            ans += Query_Update(cur * 2 + 1, mid + 1, curR, askL, askR, cover);
        PullUp(cur);
        return ans;
    }
    
    void OutPut(int cur, int l, int r, int *a, int val)
    {
        if(Sum[cur] == r - l + 1)
        {
            for (int i = l; i <= r; i++)
                a[i] = val;
            return;
        }
        PushDown(cur, l, r);
        int mid = (l + r) / 2;
        if(Sum[cur * 2])
            OutPut(cur * 2, l, mid, a, val);
        if (Sum[cur * 2 + 1])
            OutPut(cur * 2 + 1, mid + 1, r, a, val); 
    }
    
public:
    RangeTree()
    {
        memset(Cover, -1, sizeof(Cover));
    }
    
    void Init(int *a)
    {
        Init(1, 1, N, a);
    }
    
    int Query_Update(int l, int r, int cover)
    {
        return Query_Update(1, 1, N, l, r, cover);
    }
    
    void OutPut(int *a, int val)
    {
        OutPut(1, 1, N, a, val);
    }
}g[MAX_ALPHA];

int main()
{
    int opCnt;
    scanf("%d%d
", &N, &opCnt);
    for (int i = 1; i <= N; i++)
    {
        char c;
        scanf("%c", &c);
        OrgData[i] = c - 鈥榓鈥?+ 1;
    }
    for (int i = 1; i <= N; i++)
        ValPosCnt[OrgData[i]][i] += 1;
    for (int i = 1; i <= 26; i++)
        g[i].Init(ValPosCnt[i]);
    while(opCnt--)
    {
        int l, r, op;
        scanf("%d%d%d", &l, &r, &op);
        switch(op)
        {
            int prevR, prevL, num;
        case 1:
            prevR = l - 1;
            for (int i = 1; i <= 26; i++)
            {
                num = g[i].Query_Update(l, r, 0);
                if (num)
                {
                    g[i].Query_Update(prevR + 1, prevR + num, 1);
                    prevR = prevR + num;
                }
            }
            break;
        case 0:
            prevL = r + 1;
            for (int i = 1; i <= 26; i++)
            {
                num = g[i].Query_Update(l, r, 0);
                if (num)
                {
                    g[i].Query_Update(prevL - num, prevL - 1, 1);
                    prevL = prevL - num;
                }
            }
            break;
        }
    }
    static int ans[MAX_N];
    memset(ans, 0, sizeof(ans));
    for (int i = 1; i <= 26; i++)
        g[i].OutPut(ans, i);
    for (int i = 1; i <= N; i++)
        printf("%c", ans[i] + 鈥榓鈥?- 1);
    printf("
");
    return 0;
}

銆€銆€

以上是关于CF558E A Simple Task的主要内容,如果未能解决你的问题,请参考以下文章

[CF558E]A Simple Task

CF558E A Simple Task

CF558E A Simple Task

CF558E A Simple Task 线段树

Codeforces 558E A Simple Task

Codeforces 558E A Simple Task