首页 > 试题广场 >

小红的区间修改(一)

[编程题]小红的区间修改(一)
  • 热度指数:1467 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 1024M,其他语言2048M
  • 算法知识视频讲解
\hspace{15pt}本题与《F.小红的区间修改(二)》共享部分题目背景,但是所求内容不同,我们建议您重新阅读题面。

\hspace{15pt}小红拿到了一个长度为 10^{100} 的数组,初始所有元素都是 0
\hspace{15pt}现在小红准备进行 q 次操作,每一次:
\hspace{23pt}\bullet\,小红查询一个区间,如果区间内所有元素都是 0,那么将区间修改为首项为 1、公差为 1 的等差数列;否则不进行任何操作。
\hspace{15pt}小红希望你在每次操作后都输出当前数组的元素种类数,即统计数组中不同元素的个数。

输入描述:
\hspace{15pt}第一行输入一个整数 q \left(1\leqq q \leqq 3 \times 10^5\right),代表操作次数。
\hspace{15pt}此后 q 行,第 i 行输入两个整数 l_i,r_i \left(1\leqq l_i \leqq r_i \leqq 3 \times 10^5\right),代表第 i 次操作的区间。


输出描述:
\hspace{15pt}对于每一次操作,新起一行,输出一个整数,代表当前数组的元素种类数。
示例1

输入

3
1 3
2 5
5 9

输出

4
4
6

说明

\hspace{15pt}在这个样例中,数组变化如下:
\hspace{23pt}\bullet\,第一次操作后,数组变成 \{{\color{orange}{1}},{\color{orange}{2}},{\color{orange}{3}},0,0,0,\dots\}
\hspace{23pt}\bullet\,第二次操作后,数组不变;
\hspace{23pt}\bullet\,第三次操作后,数组变成 \{1,2,3,0,{\color{orange}{1}},{\color{orange}{2}},{\color{orange}{3}},{\color{orange}{4}},{\color{orange}{5}},0,0,\dots\}
使用瞪眼法,注意到,不要看错题
题目问的是整个区间的不同元素数,而不是该区间的不同元素数
注意到:我们只需要知道询问的区间里有没有其他区间就好了
就是说这个区间里没有其他l和r存在,也没有一对l和r会包含它
也就是说,查询区间pl,pr。
pl前面已经存在的l和r数量相同
pr前面已经存在的l和r数量相同
且pl和pr前面的已经存在的l和r数量都相同
这个pl和pr这个区间里就没有其他区间了
再次使用瞪眼法可知,我们需要用权值树状数组维护前面的l和r数量
使用瞪眼法可知:代码要这样写
#include<iostream>
#include<algorithm>
#include<string>
#include<vector>
#include<cmath>
#include<map>
#include<set>
#include<queue>
#include<stack>
#include<list>
#include<tuple>
#include<ctime>
#include<cstdlib>
#include<sys/timeb.h>
using namespace std;
#define ffp(x,y,z) for(ll (x) = (y);(x)<=(z);(x++))
#define ffs(x,y,z) for(ll (x) = (y);(x)>=(z);(x--))
#define pii pair<ll ,ll> 
#define ll long long int
#define q_ (qd())
const double ex = 1e-7;
const int iINF = 0x3f3f3f3f;
const ll lINF = 0x3f3f3f3f3f3f3f3f;
const ll MOD = 1000000000 + 7;
long long int qd() {
	long long w = 1, c, ret;
	while ((c = getchar()) > '9' || c < '0')
		w = (c == '-' ? -1 : 1); ret = c - '0';
	while ((c = getchar()) >= '0' && c <= '9')
		ret = ret * 10 + c - '0';
	return ret * w;
}
int stime()
{
	timeb ti;
	static bool f = 1;
	ftime(&ti);
	while (1)
	{
		if (f) { srand(ti.millitm * 117); f = 0; }

		int temp = rand();
		if (temp) { return temp > 0 ? temp : -temp; }
	}
}
ll gcd(ll a, ll b)
{
	if (a == 0)return b;
	return a % b == 0 ? b : gcd(b, a % b);
}
ll qs(ll a, ll b)
{
	ll bei = a;
	a = 1;
	while (b)
	{
		if (b & 1) { a = a * bei % MOD; }
		bei = bei * bei % MOD;
		b >>= 1;
	}
	return a;
}
ll inv(ll a)
{
	return qs(a, MOD - 2);
}
static ll Max(ll a1 = -lINF, ll a2 = -lINF, ll a3 = -lINF, ll a4 = -lINF, ll a5 = -lINF)
{
	return max(max(max(max(a1, a2), a3), a4), a5);
}
static ll Min(ll a1 = lINF, ll a2 = lINF, ll a3 = lINF, ll a4 = lINF, ll a5 = lINF)
{
	return min(min(min(min(a1, a2), a3), a4), a5);
}

void solve()
{
	int q = q_;
	vector<int>tl(300300, 0), tr(300300, 0);
	
	auto lowbit = [&](int x)->int {return x & -x; };
	auto add = [&](vector<int>& t, int p, int va)->void
		{
			while (p <= 300000)
			{
				t[p] += va;
				p += lowbit(p);
			}
		};
	auto sum = [&](vector<int>& t, int p)->int
		{
			int all=0;
			while (p)
			{
				all += t[p];
				p -= lowbit(p);
			}
			return all;
		};

	int ans = 1;
	ffp(i, 1, q)
	{
		int l = q_;
		int r = q_;
		int temp1l = sum(tl, l);
		int temp1r = sum(tr, l);
		int temp2l = sum(tl, r);
		int temp2r = sum(tr, r);
		
		if (temp1l == temp1r && temp2l == temp2r && temp1l == temp2l)
		{
			ans = max(ans, r - l + 2);
			add(tl, l, 1);
			add(tr, r, 1);
		}
		cout << ans << endl;
	}
}

int main()
{
	solve();
	return 0;
}


/*
⡀⠎⠀⠀⠀⠀⠀⠀⠀⣸⣿⣿⣿⣿⣄⠃⠈⣶⡛⠿⠭⣉⠛⠿⡿⠛⠉⣀⣠⣤⣭⡏⠴⢀⣴⣿⣿⣿⣿⣿⣿⠀⠀⠀⠀⠀⠀⠀⠙⣿⣿
⠀⠀⠀⠀⠀⠀⠀⠀⣿⣿⣿⣿⣿⣿⣷⣱⣬⠛⠉⠀⠀⢠⠀⠀⠀⢀⣀⠀⠉⠿⣿⣾⣿⣿⣿⣿⣿⣿⣿⣿⠀⠀⠀⠀⠀⠀⠀⠀⠈⡿
⠀⠀⠀⠀⠀⠀⠀⢀⢿⣿⣿⣿⣿⣿⣿⠋⠀⠀⠀⠀⠀⡏⠀⠀⠀⠀⠈⠳⠀⠀⠀⠻⣿⣿⣿⣿⣿⣿⠋⠀⣇⠀⠀⠀⠀⠀⠀⠀⠀⠈
⠀⠀⠀⠀⠀⠀⠀⣸⠀⣿⣿⣿⣿⠟⠀⠀⠀⠂⠀⠀⢠⠀⠀⠀⠀⠀⠀⠀⠈⡀⠀⠀⠀⠻⣿⣿⣿⣿⣷⡀⠘
⠀⠀⠀⠀⠀⠀⠀⣧⣿⣿⣿⣿⠋⠀⠀⠀⠀⠀⠀⠀⢸⠀⠀⠀⠀⠀⠀⠀⠀⠈⠀⠀⠀⠀⠙⣿⣿⣿⣿⣿⣄⣧
⠀⠀⠀⠀⠀⠀⣸⣿⣿⣿⣿⠁⠀⠀⠀⠀⠀⠀⠀⠀⣾⠀⠀⠀⠀⠀⠀⠀⠀⠀⢧⠀⠀⠀⠀⠈⢿⣿⣿⣿⣿⣿⣆
⠀⠀⠀⠀⠀⢀⣿⣿⣿⣿⠇⠀⠀⠀⠀⠀⠀⠀⠀⠀⢹⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⠀⠀⠀⠀⠀⢂⠻⣿⣿⣿⣿⣿⣄
⠀⠀⠀⠀⠀⣿⣿⣿⣿⣹⠀⠀⠀⠀⠀⢸⠀⠀⠀⠀⠸⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣇⠀⠀⠀⠀⠀⡄⠈⢿⣿⣿⣿⣿⣆
⠀⠀⠀⠀⣿⣿⣿⣿⠁⡇⠀⠀⠀⠀⠀⢸⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣿⠀⠀⠀⠀⠐⠸⠀⠀⠻⣿⣿⣿⣆⢦
⠀⠀⢠⣿⣿⣿⣿⠃⠀⠀⠀⠀⠀⠀⠀⣼⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡏⣧⠀⠀⠀⠀⠐⣇⠀⠀⠙⣿⣿⣿⡄⠙⣄
⠀⣴⣿⣿⣿⣿⠏⠀⢸⠀⠀⠀⠀⠀⠀⡿⢿⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣃⣈⣦⠀⠀⠀⠀⢹⠀⠀⠀⠸⣿⣿⣿⠀⠀⠳⣀
⠋⣸⣿⣿⣿⡟⠀⠀⠀⡆⠀⠀⠀⠀⠀⡏⠙⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢰⠀⢠⠀⠀⠀⢧⠀⠀⠀⠀⡇⠀⠀⠀⠘⣿⣿⣷⠀⠀⠘
⠀⣿⣿⣿⢩⠀⠀⠀⠀⣿⠀⠀⠀⠀⠀⣀⠀⢱⠀⡀⠀⠀⠀⠀⠀⠀⠀⠀⣿⠀⠂⢀⣴⣶⣿⣿⡀⠀⠀⢻⠀⠀⠀⠀⠹⣿⣿⡄
⢸⣿⣿⠃⠈⠀⠀⢸⠀⣿⣆⠀⠀⠀⠀⣿⣿⣿⠷⠘⡀⠀⠀⠀⠀⠀⠀⢠⢹⡀⠈⡿⠻⣿⣛⢿⣿⣷⡀⠈⠀⠀⠀⠀⠀⢻⣿⣿
⣿⣿⣿⠀⠀⠀⠀⢸⠀⡇⣼⣄⠀⠀⠀⢻⣿⡄⠑⠑⣿⡀⠀⠀⠀⢀⠀⠂⠇⠀⠀⠖⠛⢿⣿⣿⣌⢿⣿⣿⡆⠀⠀⠀⠀⠀⣿⣿⡀
⣿⣿⡇⠀⠀⠀⠀⢸⠀⣾⣿⣿⡷⠿⣷⣤⣿⣿⡄⠀⠀⠀⠑⠤⡀⠀⠃⠀⠀⠀⠀⣿⣶⣿⣿⣿⣿⣆⠙⣿⣧⠀⠀⠀⠀⠀⣿⣿⡇
⣿⣿⠁⠀⠀⠀⠀⠘⣾⣿⣿⠁⣴⣿⣿⣿⣿⣿⣇⠀⠀⠀⠀⠀⠀⠈⠀⠀⠀⠀⠀⠸⡏⠙⣿⠉⠻⣿⠀⠀⣿⠀⠀⠀⣄⠀⣿⢸⣷
⣿⣿⡇⠀⠀⠀⠀⠀⣿⣿⠁⠀⣿⣿⠋⣿⠏⠙⠇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢹⠀⢀⢻⠀⠀⢀⡟⢀⣿⣸⢃⠟
⣿⣿⣿⠀⡄⠀⠀⠀⠘⠻⡄⠀⢹⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡘⠀⢀⣿⠃⣿⣿⡗⠁
⣧⣿⣿⣧⢹⡀⠀⠀⠀⠱⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⠀⣴⣿⣿⣾⣿⣿⣿
⢿⠘⣿⣿⣿⣿⣤⠀⠢⡀⠱⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ ⠀⠀⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣠⣵⣿⣿⣿⣿⣿⣿⣿⣿⣷
⠀⠉⣿⣿⣿⡿⣿⠻⣷⣬⣓⣬⣄⠀⠀⠀⠀⠀⠀⠀ ⠀⠀⠉⠈⠈⠈⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣾⠃⠼⢉⣿⣿⣿⣿⣿⣿⣿
⠀⠀⣿⣿⣿⣷⠀⠀⠀⠘⣿⣄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣠⣾⣿⡏⠀⠀⢸⠀⢻⢿⣿⣿⡏⣿
⠀⢸⣿⣿⣿⣿⠀⠀⠀⠀⢻⣿⣿⣤⣀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣀⣴⣾⣿⣿⣿⣿⠀⠀⠀⢸⠀⠀⢸⣿⣿⠘⡀
⢦⡿⣿⣿⣿⢿⠀⠀⠀⠀⢸⣿⣿⣿⣿⣿⣿⣿⣶⣶⣦⡄⠀⠀⠀⠀⠀⠀⠀⠀⣰⣿⣿⣿⣿⣿⣿⣿⣿⠀⠀⠀⠘⡄⠀⠈⣿⣿⡄⠱
⣴⠛⣾⣿⣿⢸⠀⠀⠀⠀⠀⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠿⡄⠀⠀⠀⠀⠀⠀⠀⣯⠛⣿⣿⣿⣿⣿⣿⣿⠀⠀⠀⠀⣇⠀⠀⣿⣿⣿
⠿⠀⣿⣿⣿⠀⠀⠀⠀⠀⠀⣿⣿⣿⣿⣿⣿⣿⣿⠟⠰⡾⠃⠀⠀⠀⠀⠀⠀⠀⠙⡟⠀⢻⣿⣿⣿⣿⣿⡆⠀⠀⠀⠸⠀⠀⠸⣿⣿⣷
⠆⢳⣿⣿⡇⠀⠀⠀⠀⠀⠀⣿⣿⣿⠛⠿⠿⢿⡟⠀⠀⠉⠦⣀⡤⢶⠀⠖⠲⠶⠊⠀⠀⠀⢻⡛⠛⠛⣿⣿⠀⠀⠀⠀⠃⠀⠀⢿⣿⣿
*/



发表于 2025-11-30 16:43:45 回复(0)
二分写的
#include <iostream>
#include <set>

int main()
{
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr);

    int q = 0;
    std::cin>>q;
    std::set<std::pair<int,int>> set;
    int ans = 0;
    while(q--)
    {
        int l = 0,r = 0;
        std::cin>>l>>r;

        int len = r - l + 1;
        auto it_r = set.lower_bound({r,0});
        auto it_l = set.lower_bound({l,0});

        if(it_r == set.end() && it_l == set.end())
        {
            ans = std::max(ans,len);
            set.insert({r,l});
        }
        else if(it_r == set.end() && it_l != set.end())
        {
            ;
        }
        else
        {
            if(it_l != it_r)
            {
                ;
            }
            else
            {
                if(it_r->second > r)
                {
                    ans = std::max(ans,len);
                    set.insert({r,l});
                }
            }
        }
        std::cout<<ans+1<<'\n';
    }

}


发表于 2025-11-30 19:32:23 回复(0)