首页 > 其他分享 >【题解】CF848C Goodbye Souvenir

【题解】CF848C Goodbye Souvenir

时间:2023-01-14 11:11:27浏览次数:47  
标签:opt int 题解 pos CF848C lst maxn tp Goodbye

冷漠和缄默

思路

cdq 分治。

有各种懂哥写了科技做法,比如树套树和二维分块,有点离谱。

首先考虑答案的形式。

令 \(lst_i\) 为 \([1, i)\) 中 \(a_i\) 最后一次出现的位置,则对于 \([l, r]\) 的询问,答案为 \(\sum\limits_{i = l}^r i - lst_i [lst_i \geq l]\)

发现其实是对满足下面条件的 \(i - lst_i\) 求和:

  1. \(l \leq i \leq r\)

  2. \(lst_i \geq l\)

  3. 满足操作的时间轴

把初始数组抽象成 \(n\) 次修改,那么就是一个三维偏序。

直接上 cdq 分治离线下来,动态转静态做就行。

时间复杂度 \(O(n \log^2 n)\)

代码

#include <cstdio>
#include <set>
#include <algorithm>
using namespace std;

typedef long long ll;

const int maxn = 1e5 + 5;
const int maxm = 1e5 + 5;
const int opt_sz = maxn * 10;

struct opt
{
    int tp, pos, lst, nega;

    int val() { return nega * (pos - lst); }
} qry[opt_sz], tmp[opt_sz];

int n, m, len;
int a[maxn], tp[maxm];
ll ans[maxm];
set<int> pos[maxn];

namespace BIT
{
    ll c[maxn];

    int lowbit(int x) { return x & (-x); }

    void update(int p, int w) { for (int i = p; i <= n; i += lowbit(i)) c[i] += w; }

    ll query(int p)
    {
        ll res = 0;
        for (int i = p; i; i -= lowbit(i)) res += c[i];
        return res;
    }
}

void modify(int l, int tp)
{
    int lft = -1, rgt = -1;
    auto it = pos[a[l]].lower_bound(l);
    if (it != pos[a[l]].begin())
    {
        it--, lft = (*it);
        qry[++len] = (opt){1, l, lft, tp ? 1 : -1};
    }
    it = pos[a[l]].upper_bound(l);
    if (it != pos[a[l]].end())
    {
        rgt = (*it);
        qry[++len] = (opt){1, rgt, l, tp ? 1 : -1};
    }
    if ((~lft) && (~rgt)) qry[++len] = (opt){1, rgt, lft, tp ? -1 : 1};
    if (tp) pos[a[l]].insert(l);
    else pos[a[l]].erase(l);
}

void solve(int l, int r)
{
    if (l == r) return;
    int mid = (l + r) >> 1, i, j, k;
    solve(l, mid);
    solve(mid + 1, r);
    for (i = mid + 1, j = l; i <= r; i++)
    {
        if (qry[i].tp == 1) continue;
        while ((j <= mid) && (qry[j].pos <= qry[i].pos)) { if (qry[j].tp == 1) BIT::update(qry[j].lst, qry[j].val()); j++; }
        ans[qry[i].nega] += BIT::query(n) - BIT::query(qry[i].lst - 1);
    }
    for (i = l; i < j; i++)
        if (qry[i].tp == 1) BIT::update(qry[i].lst, -qry[i].val());
    for (i = l, j = mid + 1, k = l; k <= r; k++)
        if ((j > r) || ((qry[i].pos <= qry[j].pos) && (i <= mid))) tmp[k] = qry[i++];
        else tmp[k] = qry[j++];
    for (i = l; i <= r; i++) qry[i] = tmp[i];
}

int main()
{
    scanf("%d%d", &n, &m);
    for (int i = 1; i <= n; i++)
    {
        scanf("%d", &a[i]);
        pos[a[i]].insert(i);
        if (pos[a[i]].size() > 1) qry[++len] = (opt){1, i, *(--pos[a[i]].rbegin()), 1};
    }
    int qcnt = 0;
    while (m--)
    {
        int tp, l, r, v;
        scanf("%d", &tp);
        if (tp == 1)
        {
            scanf("%d%d", &l, &v);
            modify(l, 0);
            a[l] = v;
            modify(l, 1);
        }
        else
        {
            scanf("%d%d", &l, &r);
            qry[++len] = (opt){2, r, l, ++qcnt};
        }
    }
    // printf("debug %d\n", qcnt);
    solve(1, len);
    for (int i = 1; i <= qcnt; i++) printf("%lld\n", ans[i]);
    return 0;
}

标签:opt,int,题解,pos,CF848C,lst,maxn,tp,Goodbye
From: https://www.cnblogs.com/lingspace/p/cf848c.html

相关文章

  • AGC060 题解
    Wow,ChristmasRound.--Tom66A.NoMajority(1300)结论:若一个序列有严格众数,则序列中必有两个相同数字位置之差为\(1\)或\(2\)。证明设序列长为$k$,则严格......
  • vue 使用echarts图表 setOption多次很卡问题解决
    项目场景:在开发ISM组态软件时,使用echarts图表,拖拽图表很卡。问题描述在vue中使用echarts使用setOption更新加载图形很慢原因分析:由于this.echartsView=echarts.init(view,......
  • Ubuntu Server20.04 sssd+samba4共享无法访问问题解决
    UbuntuServer20.04sssd+samba4共享无法访问问题解决报错: \\ipisnotaccessible排查:在samba的log里(/var/log/samba/log.ip)能看到winbinddnotrunning解决:#apt-getins......
  • IOI 2019 题解
    Day1A排列鞋子从前往后考虑每个位置\(i\),并找到与它匹配的最靠前的元素,将这两个元素放在最靠前的空位置,最后算一下逆序对个数即可。Day1B景点划分假设\(a\leb\le......
  • 【题解】CF893F Subtree Minimum Query
    那个……令姐……能以成亲为前提……和我交往吗(娇羞)集训完刚好开方舟春活,并且我刚好攒够了给令姐买衣服的石头,这真的是巧合吗?思路各种做法,但是有强化版。首先是naive......
  • 题解 P8294 [省选联考 2022] 最大权独立集问题
    Solution根据一些逝去的记忆可以得到一个DP状态:\(f_{u,x,y}\)表示\(u\)这棵子树,\(x\)从子树出去,\(y\)进来这棵子树。然后讨论一下状态转移,可以暴力枚举状态,暴力枚......
  • CF244A Dividing Orange 题解
    Description有\(n\timesk\)个橘子,\(k\)个小朋友每人拿\(n\)个,但是每个人都指定了一个橘子\(a_i\),分配时必须要把\(a_i\)给第\(i\)个小朋友,求任一分配方案。So......
  • js加法精度问题解决
    //加法exportconstnumAdd=(num1,num2)=>{letbaseNum,baseNum1,baseNum2try{baseNum1=num1.toString().split('.')[1].length}cat......
  • maven引入本地jar不能打入部署包的问题解决
    引入的三方依赖 jar 包, scope 为 system 的包 maven 默认是不打包进去的,需要加这个配置在pom.xml文件中找到spring-boot-maven-plugin插件,添加如下配置<configu......
  • 【题解】P4126 [AHOI2009]最小割
    题意求最小割和可行边和必须边。思路清真,清真,还是**的清真。考虑可行边的充要条件:满流不存在另一条\(u,v\)间的最短路,即在残量网络上不存在包含\(u,v\)......