洛谷—P1903—[国家集训队]数颜色 / 维护队列 离散化+暴力优化
前两天学莫队的时候,在余姚集训的好看小姐姐给小萌新推荐了一道带修莫队题。
当时觉得用莫队写应该不是很难,就放下了一直没写。没想到今天讲课的好看学姐就把这个题布置出来了
本来准备老老实实写带修莫队,结果在某
去向小姐姐炫耀了一下结果被嘲讽交你咕会挂,顺带被小姐姐再次教育了一番要好好写莫队。
你咕数据有加强,刚开始爆彩虹,
然后成功地俘获了小姐姐芳心,应她的要求才来写的题解[大雾]
好了进入正题(前面讲那么多只是为了让各位
这篇暴力和外面那些妖艳暴力可不一样(手动狗头)。
大体思路嘛······暴力还需要什么思路。在线做,如果要求修改就直接修改,如果要询问就从
但是这样子会
-
离散化,不需要
sort + unique ,只需要额外开个数组复制一下即可,简单粗暴(不然怎么叫暴力) -
我们发现每次暴力查询
l \longrightarrow r 的时候都需要memset 一遍vis 数组,所以我们可以采用标号法,即扫的过程中若vis[a[ j ]] 还不是i 就把他赋成i ,并把ans 加一。别的就真的没什么好说的了,暴力即可。
附上
AC 代码,数组开的比较匆忙,可能开大了。记得吸氧,不然90 。// luogu-judger-enable-o2 #include<stdio.h> #define maxn 10000005 #define maxm 100005 using namespace std; int n, m, l, r, ans, cnt = 0; int a[maxn], b[maxm]; int vis[maxm + 10000]; char c; inline int read() { int s = 0, w = 1; char ch = getchar(); while( ch < '0' || ch > '9' ) { if( ch == '-' ) w = -1; ch = getchar(); } while( ch >= '0' && ch <= '9' ) { s = s * 10 + ch - '0'; ch = getchar(); } return s * w; } int main() { n = read(); m = read(); for( int i = 1; i <= n; i ++ ) { int o = read(); if( !a[o] ) a[o] = ++ cnt; b[i] = a[o]; } for( int i = 1; i <= m; i ++ ) { c = ' '; while( c != 'Q' && c != 'R' ) c = getchar(); l = read(); r = read(); if( c == 'R' ) { if( !a[r] ) a[r] = ++ cnt; b[l] = a[r]; continue; } ans = 0; for( int j = l; j <= r; j ++ ) { if( vis[b[j]] != i ) { ans ++; vis[b[j]] = i; } } printf( "%d\n", ans ); } }