7,8,9,10四个点tle
查看原帖
7,8,9,10四个点tle
762556
3demonsky楼主2024/11/28 20:57

下面是代码,之前提交7也没卡,改了之后7也卡了

#include <iostream>
#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int MAXN = 1e6 + 5;
const int MAXQ = 1e6 + 5;
int N, M;
int a[MAXN];
// 莫队
int ans[MAXQ];
// 块大小
int size;
struct Query
{
    // 区间
    int l, r;
    // 时间戳
    int t;
    // 询问前的修改数量
    int changes;
} query[MAXQ];
// 询问的数量
int Qtot = 0;
// 修改
struct Change
{
    // 下标
    int id;
    // 新值
    int val;
} change[MAXN];
// 修改的数量
int Ctot = 0;
bool cmp(Query a, Query b)
{
    // 左端点不在同一个块内
    if ((a.l / size) != (b.l / size))
        return a.l < b.l;
    else if (a.r != b.r)
        return a.r < b.r;
    else
        return a.changes < b.changes;
}
int f[MAXN];
ll num = 0;
// 区间移动
void del(int x)
{
    f[a[x]]--;
    if (f[a[x]] == 0)
        num--;
}
void add(int x)
{
    f[a[x]]++;
    if (f[a[x]] == 1)
        num++;
}
void tupdate(int x)
{
    f[a[change[x].id]]--;
    if (f[a[change[x].id]] == 0)
        num--;
    f[change[x].val]++;
    if (f[change[x].val] == 1)
        num++;
}

int main()
{
    // 数据读取
    cin >> N >> M;
    size = sqrt(N);
    for (int i = 1; i <= N; i++)
        cin >> a[i];
    for (int i = 1; i <= M; i++)
    {
        char c;
        int x, y;
        cin >> c >> x >> y;
        if (c == 'Q')
        {
            Qtot++;
            query[Qtot].l = x;
            query[Qtot].r = y;
            query[Qtot].t = Qtot;
            query[Qtot].changes = Ctot;
        }
        else
        {
            Ctot++;
            change[Ctot].id = x;
            change[Ctot].val = y;
        }
    }
    // 当前区间
    int x = 1, y = 0;
    // 当前已经处理修改数量
    int modify = 0;
    // 排序
    sort(query + 1, query + Qtot + 1, cmp);
    // 处理每次的询问
    for (int i = 1; i <= Qtot; i++)
    {
        // 正常莫队修改
        while (y < query[i].r)
            add(++y);
        while (x > query[i].l)
            add(--x);
        while (y > query[i].r)
            del(y--);
        while (x < query[i].l)
            del(x++);
        // 增加时间维修改
        while (modify < query[i].changes)
        {
            modify++;
            if (change[modify].id <= query[i].r && change[modify].id >= query[i].l)
                tupdate(modify);
            swap(a[change[modify].id], change[modify].val);
        }
        while (modify > query[i].changes)
        {
            if (change[modify].id <= query[i].r && change[modify].id >= query[i].l)
                tupdate(modify);
            swap(a[change[modify].id], change[modify].val);
            modify--;
        }
        ans[query[i].t] = num;
    }
    for (int i = 1; i <= Qtot; i++)
        cout << ans[i] << endl;
    return 0;
}
2024/11/28 20:57
加载中...