ABC F求调
  • 板块学术版
  • 楼主sqrtqwq
  • 当前回复0
  • 已保存回复0
  • 发布时间2024/3/2 21:58
  • 上次更新2024/3/3 09:40:39
查看原帖
ABC F求调
507374
sqrtqwq楼主2024/3/2 21:58

RT,使用分块直接做。

#include<bits/stdc++.h>
using namespace std;
const int maxn = 4e5 + 10;
const int B = 1000;

struct node
{
    int d,pos;
    bool flag;
}a[maxn];

int C[maxn];
int tmp[maxn];
int len,num;
int mx[maxn],mxx[maxn];
int sum[B][maxn];

struct query
{
    int opt,l,r;
}q[maxn];

int n,m;
int block[maxn];

void init()
{
    num = n / len;
    for(int i = 1;i <= num;i++)
    {
        for(int j = (i - 1) * len + 1;j <= min(n,i * len);j++)
        {
            block[j] = i;
        }
    }
    if(num * len < n)
    {
        num++;
        for(int j = (num - 1) * len + 1;j <= n;j++)
        {
            block[j] = num;
        }
    }
    for(int i = 1;i <= n;i++)
    {
        sum[block[i]][a[i].d]++;
        if(a[i].d > mx[block[i]])
        {
            mxx[block[i]] = mx[block[i]];
            mx[block[i]] = a[i].d;
        }
        else if(a[i].d > mxx[block[i]] && mx[block[i]] != a[i].d)
        {
            mxx[block[i]] = a[i].d;
        }
    }
}

int main()
{
    cin >> n >> m;
    len = sqrt(n);
    int cnt = 0;
    for(int i = 1;i <= n;i++)
    {
        cin >> a[i].d;
        tmp[++cnt] = a[i].d;
    }
    for(int i = 1;i <= m;i++)
    {
        cin >> q[i].opt >> q[i].l >> q[i].r;
        if(q[i].opt == 1)
        {
            tmp[++cnt] = q[i].r;
            a[++cnt].d = q[i].r;
            a[cnt].flag = 1;
            a[cnt].pos = i;
        }
    }
    sort(tmp + 1,tmp + cnt + 1);
    int cnt1 = unique(tmp + 1,tmp + cnt + 1) - tmp - 1;
    for(int i = 1;i <= cnt;i++)
    {
        a[i].d = lower_bound(tmp + 1,tmp + cnt1 + 1,a[i].d) - tmp;
        if(a[i].flag)
        {
            q[a[i].pos].r = a[i].d;
        }
    }
    init();
    for(int i = 1;i <= m;i++)
    {
        int l = q[i].l,r = q[i].r;
        if(q[i].opt == 1)
        {
            sum[block[l]][a[l].d]--;
            a[l].d = r;
            sum[block[l]][a[l].d]++;
            mxx[block[l]] = mx[block[l]] = -63;
            for(int j = (block[l] - 1) * len + 1;j <= min(n,block[l] * len);j++)
            {
                if(a[j].d > mx[block[j]])
                {
                    mxx[block[j]] = mx[block[j]];
                    mx[block[j]] = a[j].d;
                }
                else if(a[j].d > mxx[block[j]] && mx[block[j]] != a[j].d)
                {
                    mxx[block[j]] = a[j].d;
                }
            }
        }
        else
        {
            int maxx = -63,maxxx = -63;
            if(l == r)cout << 0 << '\n';
            else
            {
                for(int j = block[l] + 1;j <= block[r] - 1;j++)
                {
                    if(mx[j] > maxx)
                    {
                        maxxx = maxx;
                        maxx = mx[j];
                    }
                    else if(mx[j] > maxxx && maxx != mx[j])
                    {
                        maxxx = mx[j];
                    }
                    if(mxx[j] > maxx)
                    {
                        maxxx = maxx;
                        maxx = mxx[j];
                    }
                    else if(mxx[j] > maxxx && maxx != mxx[j])
                    {
                        maxxx = mxx[j];
                    }
                }
                for(int j = l;j <= min(block[l] * len,n);j++)
                {
                    if(a[j].d > maxx)
                    {
                        maxxx = maxx;
                        maxx = a[j].d;
                    }
                    else if(a[j].d > maxxx && a[j].d != maxx)
                    {
                        maxxx = a[j].d;
                    }
                }
                for(int j = (block[r] - 1) * len + 1;j <= r;j++)
                {
                    if(a[j].d > maxx)
                    {
                        maxxx = maxx;
                        maxx = a[j].d;
                    }
                    else if(a[j].d > maxxx && a[j].d != maxx)
                    {
                        maxxx = a[j].d;
                    }
                }
                int ans = 0;
                for(int j = block[l] + 1;j <= block[r] - 1;j++)
                {
                    ans += sum[j][maxxx];
                }
                for(int j = l;j <= min(block[l] * len,n);j++)
                {
                    if(a[j].d == maxxx)
                    {
                        ans++;
                    }
                }
                for(int j = (block[r] - 1) * len + 1;j <= r;j++)
                {
                    if(a[j].d == maxxx)
                    {
                        ans++;
                    }
                }
                cout << ans << '\n';
            }
        }
    }
    return 0;
}//肥肠暴力的分块做法

2024/3/2 21:58
加载中...