序列操作(代码源每日一题)

序列操作(代码源每日一题)

序列操作 - 题目 - Daimayuan Online Judge

思维

  1. 要观察到两种操作的性质:

    1. 单点修改的优先级是最高的,所以一个位置有且只有最后一次单点修改起作用
    2. 在不考虑单点修改的情况下,只有最大的 y 的操作才起作用
  2. 接下来思考在操作 2 中如何不考虑单点修改

    如果记录下每个位置最后一次单点修改的时间,这个位置之后的值只与这个时间以后最大的 2 操作有关

  3. 因此只需记录下每个位置最后一次单点修改的时间并修改,维护每个时间 2 操作的后缀最大值,对于每个位置最终的答案就是 max(最后一次单点修改的值,最后一次单点修改时间的 2 操作的后缀最大值)

#include <iostream>
#include <algorithm>
#include <cstring>
#include <vector>
#include <cmath>
#include <queue>
using namespace std;
#define endl "\n"

typedef long long ll;
typedef pair<int, int> PII;

const int N = 1e5 + 10;

int a[N], s[N];
int n;
int mp[N];
int main()
{
	ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
	cin >> n;
	for (int i = 1; i <= n; i++)
	{
		cin >> a[i];
		s[i] = (s[i-1] + a[i]) % n;
	}
	for (int i = 1; i <= n; i++)
	{
		if (s[i] == 0)
		{
			cout << i << endl;
			for (int j = 1; j <= i; j++)
				cout << j << " ";
			cout << endl;
			return 0;
		}
	}
	for (int i = 1; i <= n; i++)
	{
		if (mp[s[i]] == 0)
			mp[s[i]] = i;
		else
		{
			cout << i - mp[s[i]] << endl;
			for (int j = mp[s[i]] + 1; j <= i; j++)
				cout << j << " ";
			cout << endl;
			return 0;
		}
	}
    return 0;
}
posted @ 2022-06-13 14:56  hzy0227  阅读(31)  评论(0编辑  收藏  举报