数颜色

Posted zubizakeli

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了数颜色相关的知识,希望对你有一定的参考价值。

     题意:

  n个数,m个操作。

  •  查询区间[a,b]内不同数字数
  •  将某个数修改为c

  题解:

  带修改莫队。

    与普通莫队不同的就是要记录一下每个查询操作前有多少个修改操作,然后暴力修改或改回去。

 

  题目链接:https://www.luogu.org/problemnew/show/P1903

 

 

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#define LL long long
#define RI register int
using namespace std;
const int INF = 0x7ffffff ;
const int S = 1e6 + 10 ;
const int N = 10000 + 10 ;

inline int read() {
    int k = 0 , f = 1 ; char c = getchar() ;
    for( ; !isdigit(c) ; c = getchar())
      if(c == -) f = -1 ;
    for( ; isdigit(c) ; c = getchar())
      k = k*10 + c-0 ;
    return k*f ;
}

struct Que {
    int l, r, ti, id ;
}q[N] ;

int n, m, qcnt = 0, rcnt = 0, hh[N], pp[1010], cc[1010], res[N], pos[N], num[S], ans = 0 ;
int L = 1, R = 0, T = 0 ;

inline bool cmp1(Que s,Que t) {  // 其实我也不知道怎么排序最快qaq 
    if(pos[s.l] == pos[t.l]) {
        if(pos[s.r] == pos[t.r]) return s.ti < t.ti ;
        return s.r < t.r ;
    } 
    return s.l < t.l ;
}

inline void add(int x) {
    if(!num[hh[x]]) ans ++ ;
    num[hh[x]] ++ ;
}
inline void del(int x) {
    num[hh[x]] -- ;
    if(!num[hh[x]]) ans -- ;
}
inline void addt(int t) {
    if(pp[t] >= L && pp[t] <= R) {
        num[hh[pp[t]]] -- ;
        if(!num[hh[pp[t]]]) ans -- ;
        if(!num[cc[t]]) ans ++ ;
        num[cc[t]] ++ ;
    }
    swap(hh[pp[t]],cc[t]) ;
    // 这是一步很神奇的操作
    // 因为记录每个位置的历史值显然是十分麻烦的。
    // 我们可以观察一个性质就是当一个修改操作被改回去时,就是原值变成修改值,修改值变成原值
    // 所以只要交换一下即可 
}

int main() {
    n = read(), m = read() ;
    int base = sqrt(n) ;
    for(int i=1;i<=n;i++) hh[i] = read(), pos[i] = (i-1)/base + 1 ;
    char cs ;
    for(int i=1;i<=m;i++) {
        cin>>cs ;
        if(cs == Q) {
            q[++qcnt].l = read(), q[qcnt].r = read() ;
            q[qcnt].ti = rcnt ; q[qcnt].id = qcnt ;
        } else {
            pp[++rcnt] = read(), cc[rcnt] = read() ;
        }
    }
    sort(q+1,q+qcnt+1,cmp1) ;
    for(int i=1;i<=qcnt;i++) {
        while(L < q[i].l) del(L++) ;
        while(L > q[i].l) add(--L) ;
        while(R < q[i].r) add(++R) ;
        while(R > q[i].r) del(R--) ; // 以上与普通莫队相同 
        while(T < q[i].ti) addt(++T) ;
        while(T > q[i].ti) addt(T--) ; // 为什么都是add操作呢?看看addt函数就知道了qwq 
        res[q[i].id] = ans ;
    }
    for(int i=1;i<=qcnt;i++) {
        printf("%d\n",res[i]) ;
    }
    return 0 ;
}

 

 PS:scanf读单字符时不忽略空格与换行符T_T,换用cin即可.

以上是关于数颜色的主要内容,如果未能解决你的问题,请参考以下文章

有没有办法以编程方式使用kotlin更改片段中的文本颜色?

c_cpp UV Index Indicator订阅PubNub并使用颜色显示UV索引值。博文的代码片段。在这里查看项目:https:/

如何从 RCNN 中裁剪分割的对象?

代码片段如何使用CSS来快速定义多彩光标

使用颜色选择器更改片段中edittext的背景颜色

片段着色器会覆盖光栅化生成的片段颜色吗?