據說暴力可過2200ms。。。然而我寫分塊也才1200ms。。然而很多人寫分塊跑不過暴力。。。
參考了將狼踩盡(的思路。假設分為m塊(注意不是每塊m個)。用sum[x][y][z]表示在塊x~y中顏色z(經過離散化以後)的個數,val[x][y]表示在x~y塊中不同顏色的個數。這樣應該就比較容易明白了。
修改:看u會影響那些val[x][y],然後根據sum的值得到val是否要加減,具體看**;
查詢:不能簡單的像普通的分塊那樣進行,要利用現有的。比如查詢x~y,它經過的完整的塊是u~v,那麼我們就可以假設將x~u以及v~y中的顏色插入到val[u][v]中,然後就可以根據修改的模式進行查詢了,答案就是val[u][v]。但是最後要復原。
初始化時間複雜度為o(m^2n),修改時最壞經過o(m^2)次,查詢主要是零碎部分o(n/m)。總的時間複雜度o(m^2n+m(m^2+n/m)),可以看到,當m=n^(1/3)時時間複雜度最小為o(n^(5/3))。
ac**如下:
#include#include#include#includeusing namespace std;
int n,m,size,cnt,tot,blg[20005],a[20005],f[1000005],l[30],r[30],sum[30][30][20005],val[30][30];
void qry(int x,int y)
printf("%d\n",val[u][v]);
for (i=x; ir[v] && i>=x; i--)
}int main()
if (r[cnt]'z') ch=getchar();
int x,y; scanf("%d%d",&x,&y);
if (ch=='q') qry(x,y); else
if (!f[y]) f[y]=++tot; a[x]=f[y];
for (i=1; i<=cnt; i++) for (j=i; j<=cnt; j++) if (l[i]<=x && x<=r[j])
} }return 0;
}
by lych
2016.2 5
BZOJ 2120 數顏色 分塊
time limit 6 sec memory limit 259 mb submit 6031 solved 2392 submit status discuss 墨墨購買了一套n支彩色畫筆 其中有些顏色可能相同 擺成一排,你需要回答墨墨的提問。墨墨會像你發布如下指令 1 q l r代表詢問你從第...
bzoj 2120 數顏色 (分塊做法)
此篇文章主要講修改操作 用pre i 表示第i個元素的前乙個相同元素的位置,問題變成在區間 l,r 裡找大於l的數的個數,具體什麼意思去其他地方看 預設值為最大值。用ppp i 表示顏色i最後出現的位置 針對這道題顏色最多1e6種,建乙個1e6的陣列即可 color i 表示第i個位置是什麼顏色 總...
BZOJ 2120 數顏色 莫隊
題目傳送門 觀察前兩題,莫隊演算法好像是一種只支援查詢的離線演算法,但是莫隊真的不支援修改嗎?答案當然是否定的 莫隊是一種支援查詢和修改的離線演算法。就是一種優美的暴力 考慮在莫隊演算法中增加乙個變數no w 表示當前有no w 個修改已經修改掉了。並在每乙個詢問中增加乙個變數pr e 表示最近的修...