[CF1450D] Rating Compression(树状数组+单调栈)

原题

思路

permutation要满足两个条件:1.对于长度为n的排列,最大值为n;2.排列中每个数只出现一次。

可以用树状数组记录每个数出现的次数,再用cnt记录出现超过一次的数的个数,如果从cnt == 0 && sum(n) == n ,则满足permutation条件。

接下来就是处理k每增加一,每个数出现次数的变化,可以把每次k+1序列产生的变化想成一次合并,\(b_i = min(a_i, a_{i+1})\), 形成长度为n - 1的序列,如果\(a_i > a_{i+1}\),\(ai\)就会被\(a_{i+1}\)取代,同样,如果\(a_i < a_{i-1}\), \(a_i\)就会取代\(a_{i - 1}\),那么\(a_i\)在第m次之后会被完全取代掉, m = 前面连续>ai的个数+后面连续>=ai的个数。

单调栈预处理出每个ai会被完全取代的k值,放到优先队列,对每个k值进行一次判断即可。

p.s.双指针的做法代码简单很多,但是我没想到

p.p.s.发现permutation这个词在很多题目里都像本题中的情况一样,要满足1-n不重复的出现,不知道是这个词本身可以特指这一种排列还是啥

p.p.p.s.祭奠我一周掉了200分的cf

#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <list>
#include <map>
#include <iostream>
#include <iomanip>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <unordered_map>
#include <vector>
#define LL long long
#define inf 0x3f3f3f3f
#define INF 0x3f3f3f3f3f3f
#define PI 3.1415926535898
#define F first
#define S second
#define endl '\n'
#define lson rt << 1
#define rson rt << 1 | 1
#define lowbit(x) (x & (-x))
#define f(x, y, z) for (int x = (y), __ = (z); x < __; ++x)
#define _rep(i, a, b) for (int i = (a); i <= (b); ++i)
#define _per(i, a, b) for (int i = (a); i >= (b); --i)
using namespace std;
 
const int maxn = 3e5 + 7;
const int maxm = 1e3 + 7;
int n;
int a[maxn], c[maxn], pre[maxn], tail[maxn], num[maxn];
void update(int x, int y)
{
    for (; x <= n; x += lowbit(x))
        c[x] += y;
}
int sum(int x)
{
    int ans = 0;
    for (; x; x -= lowbit(x))
        ans += c[x];
    return ans;
}
struct node
{
    int val, tim;
    bool operator<(const node &a) const
    {
        return a.tim < tim;
    }
};
 
void init()
{
    _rep(i, 1, n)
    {
        num[i] = c[i] = 0;
    }
}
 
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    int t;
    cin >> t;
    while (t--)
    {
        cin >> n;
        init();
        _rep(i, 1, n) cin >> a[i];
        stack<pair<int, int>> s;
        _rep(i, 1, n)
        {
            while (!s.empty() && s.top().F > a[i])
                s.pop();
            if (!s.empty())
                pre[i] = i - s.top().S - 1;
            else
                pre[i] = i - 1;
            s.push({a[i], i});
        }
        while (!s.empty())
            s.pop();
        _per(i, n, 1)
        {
            while (!s.empty() && s.top().F >= a[i])
                s.pop();
            if (!s.empty())
                tail[i] = s.top().S - i - 1;
            else
                tail[i] = n - i;
            s.push({a[i], i});
        }
        priority_queue<node> q;
        int cnt = 0;
        _rep(i, 1, n)
        {
            q.push({a[i], pre[i] + tail[i] + 1});
            update(a[i], 1);
            num[a[i]]++;
            if (num[a[i]] == 2)
                cnt++;
        }
        _rep(tim, 0, n - 1)
        {
            while (!q.empty() && q.top().tim == tim)
            {
                int u = q.top().val;
                q.pop();
                update(u, -1);
                num[u]--;
                if (num[u] == 1)
                    cnt--;
            }
            if (!cnt && sum(n - tim) == n - tim)
                cout << 1;
            else
                cout << 0;
        }
        cout << endl;
    }
}
posted @ 2020-12-10 00:13  kurum!  阅读(85)  评论(0编辑  收藏  举报