码迷,mamicode.com
首页 > 其他好文 > 详细

【Luogu1903】数颜色(带修莫队)

时间:2020-11-21 11:54:33      阅读:4      评论:0      收藏:0      [点我收藏+]

标签:pos   lang   odi   www   type   turn   三个点   dig   isa   

Link:
https://www.luogu.com.cn/problem/P1903


Solution

这个 sort
我暂且蒙在鼓里
先贴个代码。

本来我 T 了三个点的 cmp 函数如下

bool cmp(const s_q &a, const s_q &b)
{
    if (belong[a.x] == belong[b.x])
    {
        if (a.y == b.y)
        {
            if (belong[a.x] & 1) return a.t < b.t;
            return a.t > b.t;
        }
        if (belong[a.x] & 1)
        {
            return a.y < b.y;
        }
        return a.y > b.y;
    }
    return belong[a.x] < belong[b.x];
}

貌似跟我想的有些差距
等我回来补上



Code

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstdlib>
#include<cstring>
#include<cctype>
#include<cmath>

using namespace std;

char frBB[1<<12], *frS=frBB, *frT=frBB;
#define getchar() (frS==frT&&(frT=(frS=frBB)+fread(frBB,1,1<<12,stdin),frS==frT)?EOF:*frS++)
double _db_read()
{
    bool w = 0; char ch = 0; double x = 0;
    while (!isdigit(ch)) w |= ch == ‘-‘, ch = getchar();
    while (isdigit(ch)) x = x * 10 + (ch ^ 48), ch = getchar();
    if (ch == ‘.‘)
    {
		double y = 1.0; ch = getchar();
        while (isdigit(ch)) x += (y /= 10) * (ch ^ 48), ch = getchar();
    }
    return w ? -x : x;
}
int _n_read()
{
    bool w = 0; char ch = 0; int x = 0;
    while (!isdigit(ch)) w |= ch == ‘-‘, ch = getchar();
    while (isdigit(ch)) x = x * 10 + (ch ^ 48), ch = getchar();
    return w ? -x : x;
}
#define read(x) x=_n_read()

const int MAXN = 15e4;
const int MAXC = 1e6 + 10;

int n, m, _Time = 0, block_siz, block_cnt, belong[MAXN], col[MAXN], _col_Temp[MAXN];

int Modify_Target[MAXN], Modify_Result[MAXN], Before_Modify[MAXN], _m_Temp = 0;

int Bucket[MAXC];

int Answer[MAXN];

struct s_q
{
    int id, x, y, t;

    // type == 1 :
    // x : Query_L
    // y : Query_R

    s_q(const int &aug1 = 0, const int &aug2 = 0, const int &aug3 = 0, const int &aug4 = 0)
    {
        id = aug1;
        x = aug2;
        y = aug3;
        t = aug4;
    }

} sq[MAXN];

bool cmp(const s_q &a, const s_q &b)
{
	if (belong[a.x] != belong[b.x]) return belong[a.x] < belong[b.x];
	if (belong[a.y] != belong[b.y]) return belong[a.y] < belong[b.y	];
	return a.t < b.t;	
}

int main()
{
    read(n);
    read(m);

    for (int i = 1; i <= n; ++i)
    {
        read(col[i]);
        _col_Temp[i] = col[i];
    }

    // Queries+ReadIn
    {
        char ch;

        for (int i = 1; i <= m; ++i)
        {
        	while(ch = getchar())
        	{
        		if (isalpha(ch)) break;
        	}

            if (ch == ‘Q‘)
            {
                sq[++_m_Temp].t = _Time;
                read(sq[_m_Temp].x);
                read(sq[_m_Temp].y);
                sq[_m_Temp].id = _m_Temp;
                continue;
            }

            // ch == ‘R‘
            {
                ++_Time;
                read(Modify_Target[_Time]);
                read(Modify_Result[_Time]);
                Before_Modify[_Time] = _col_Temp[Modify_Target[_Time]];
                _col_Temp[Modify_Target[_Time]] = Modify_Result[_Time];
            }
        }

        m = _m_Temp;
    }

    block_siz = ceil(pow(n, 0.75));

    for (int cur_block_id = 1, cur_block_pos = 0, i = 1; i <= n; ++i)
    {
        ++cur_block_pos;
        if (cur_block_pos == block_siz + 1)
        {
            ++cur_block_id;
            cur_block_pos = 1;
        }
        belong[i] = cur_block_id;
    }

    block_cnt = belong[n];

    sort(sq + 1, sq + 1 + m, cmp);

    // Run+DaiXiu_MoDui
    {
        int l = 1, r = 0, t = 0;

        for (int _answer_Temp = 0, i = 1; i <= m; ++i)
        {

            while (l < sq[i].x)
            {
                _answer_Temp -= !--Bucket[col[l++]];
            }
            while (l > sq[i].x)
            {
                _answer_Temp += !Bucket[col[--l]]++;
            }
            while (r < sq[i].y)
            {
                _answer_Temp += !Bucket[col[++r]]++;
            }
            while (r > sq[i].y)
            {
                _answer_Temp -= !--Bucket[col[r--]];
            }
            while (t < sq[i].t)
            {
                ++t;
                if (sq[i].x <= Modify_Target[t] && Modify_Target[t] <= sq[i].y)
                {
                    _answer_Temp -= !--Bucket[col[Modify_Target[t]]];
                    _answer_Temp += !Bucket[Modify_Result[t]]++;
                }
                col[Modify_Target[t]] = Modify_Result[t];
            }
            while (t > sq[i].t)
            {
                if (sq[i].x <= Modify_Target[t] && Modify_Target[t] <= sq[i].y)
                {
                    _answer_Temp -= !--Bucket[col[Modify_Target[t]]];
                    _answer_Temp += !Bucket[Before_Modify[t]]++;
                }
                col[Modify_Target[t]] = Before_Modify[t];
                --t;
            }
            Answer[sq[i].id] = _answer_Temp;
        }
    }

    for (int i = 1; i <= m; ++i)
    {
    	printf("%d\n", Answer[i]);
    }

    return 0;
}

【Luogu1903】数颜色(带修莫队)

标签:pos   lang   odi   www   type   turn   三个点   dig   isa   

原文地址:https://www.cnblogs.com/ccryolitecc/p/13991822.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!