BZOJ-2743: [HEOI2012]采花(樹狀數組 or TLE莫隊)
阿新 • • 發佈:2017-10-19
open 一個 sea 水題 ++ 莫隊 spa 高手 一道
Submit: 2512 Solved: 1292
[Submit][Status][Discuss]
1 2 2 3 1
1 5
1 2
2 2
2 3
3 5
0 0 1 0
【樣例說明】
詢問[1, 5]:公主采顏色為1和2的花,由於顏色3的花只有一朵,公主不采;詢問[1, 2]:顏色1和顏色2的花均只有一朵,公主不采;
詢問[2, 2]:顏色2的花只有一朵,公主不采;
詢問[2, 3]:由於顏色2的花有兩朵,公主采顏色2的花;
詢問[3, 5]:顏色1、2、3的花各一朵,公主不采。
2743: [HEOI2012]采花
Time Limit: 15 Sec Memory Limit: 128 MBSubmit: 2512 Solved: 1292
[Submit][Status][Discuss]
Description
蕭蕓斕是Z國的公主,平時的一大愛好是采花。 今天天氣晴朗,陽光明媚,公主清晨便去了皇宮中新建的花園采花。花園足夠大,容納了n朵花,花有c種顏色(用整數1-c表示),且花是排成一排的,以便於公主采花。公主每次采花後會統計采到的花的顏色數,顏色數越多她會越高興!同時,她有一癖好,她不允許最後自己采到的花中,某一顏色的花只有一朵。為此,公主每采一朵花,要麽此前已采到此顏色的花,要麽有相當正確的直覺告訴她,她必能再次采到此顏色的花。由於時間關系,公主只能走過花園連續的一段進行采花,便讓女仆福涵潔安排行程。福涵潔綜合各種因素擬定了m個行程,然後一一向你詢問公主能采到多少朵花(她知道你是編程高手,定能快速給出答案!),最後會選擇令公主最高興的行程(為了拿到更多獎金!)。Input
第一行四個空格隔開的整數n、c以及m。接下來一行n個空格隔開的整數,每個數在[1, c]間,第i個數表示第i朵花的顏色。接下來m行每行兩個空格隔開的整數l和r(l ≤ r),表示女仆安排的行程為公主經過第l到第r朵花進行采花。
Output
共m行,每行一個整數,第i個數表示公主在女仆的第i個行程中能采到的花的顏色數。Sample Input
5 3 51 2 2 3 1
1 5
1 2
2 2
2 3
3 5
Sample Output
20 0 1 0
【樣例說明】
詢問[1, 5]:公主采顏色為1和2的花,由於顏色3的花只有一朵,公主不采;詢問[1, 2]:顏色1和顏色2的花均只有一朵,公主不采;
詢問[2, 2]:顏色2的花只有一朵,公主不采;
詢問[2, 3]:由於顏色2的花有兩朵,公主采顏色2的花;
詢問[3, 5]:顏色1、2、3的花各一朵,公主不采。
HINT
【數據範圍】
對於100%的數據,1 ≤ n ≤ 10^6,c ≤ n,m ≤10^6。
Source
看到題目第一眼……mmp這不是傻逼莫隊嘛……於是怒懟了一個莫隊上去,評測的時候laj還想說laj又做了bzoj上的一道水題呢mmp結果先是PE結果後來全是TLE……一看數據mmp 1e6 莫隊個jb啊(好吧這道傻逼題搞了我兩節半課才搞好QAQ)
先貼個莫隊的TLE代碼。。
1 #include "bits/stdc++.h" 2 using namespace std; 3 typedef long long LL; 4 const int MAX=1e6+5; 5 int n,m,faq; 6 int a[MAX],b[MAX],pos[MAX],bas,ans,an[MAX]; 7 struct Node{ 8 int id; 9 int l,r; 10 bool operator < (const Node &tt) const { 11 if (pos[l]!=pos[tt.l]) 12 return pos[l]<pos[tt.l]; 13 return r<tt.r; 14 } 15 }que[MAX]; 16 inline int read(){ 17 int an=0,x=1;char c=getchar(); 18 while (c<‘0‘ || c>‘9‘) {if (c==‘-‘) x=-1;c=getchar();} 19 while (c>=‘0‘ && c<=‘9‘) {an=an*10+c-‘0‘;c=getchar();} 20 return an*x; 21 } 22 void update(int x,int y){ 23 ans-=(b[a[x]]>1?1:0); 24 b[a[x]]+=y; 25 ans+=(b[a[x]]>1?1:0); 26 } 27 int main(){ 28 freopen ("flower.in","r",stdin); 29 freopen ("flower.out","w",stdout); 30 register int i,j; 31 n=read(),faq=read(),m=read();bas=(int)sqrt(n*1.0); 32 for (i=1;i<=n;++i) a[i]=read(),pos[i]=i/bas; 33 for (i=1;i<=m;++i){ 34 que[i].id=i, 35 que[i].l=read(),que[i].r=read(); 36 } 37 sort(que+1,que+m+1); 38 memset(b,0,sizeof(b)); 39 register int L=1,R=0; 40 for (i=1;i<=m;++i){ 41 while (R<que[i].r) update(++R,1); 42 while (L>que[i].l) update(--L,1); 43 while (R>que[i].r) update(R--,-1); 44 while (L<que[i].l) update(L++,-1); 45 an[que[i].id]=ans; 46 } 47 for (i=1;i<m;++i) 48 printf("%d\n",an[i]); 49 printf("%d",an[m]); 50 return 0; 51 }
好吧好吧滾去寫樹狀數組,看懂了hzwer的HH的項鏈還有這題,又在luogu上TLE了無數遍最後終於AC了mmp
為什麽不寫思路呢……因為我也講不出來,只可意會,不可言傳 ovo 應該說HH的項鏈是初始化和每次操作都是把下一位標1,此題首先初始化就把下下位標1然後操作是把下一位(也就是上一位的下下位)去掉,再把當前位的下下位標1。。。
1 #include "bits/stdc++.h" 2 using namespace std; 3 typedef long long LL; 4 const int MAX=1e6+5; 5 int n,m,faq; 6 int a[MAX],b[MAX],next[MAX],p[MAX],an[MAX]; 7 struct Node{ 8 int id; 9 int l,r; 10 bool operator < (const Node &tt) const {return l<tt.l;} 11 }que[MAX]; 12 inline int read(){ 13 int an=0,x=1;char c=getchar(); 14 while (c<‘0‘ || c>‘9‘) {if (c==‘-‘) x=-1;c=getchar();} 15 while (c>=‘0‘ && c<=‘9‘) {an=an*10+c-‘0‘;c=getchar();} 16 return an*x; 17 } 18 void add(int x,int y){for (;x<=n;x+=(x&-x)) b[x]+=y;} 19 inline int search(int x){int an=0;for (;x>0;x-=(x&-x)) an+=b[x];return an;} 20 int main(){ 21 freopen ("flower.in","r",stdin); 22 freopen ("flower.out","w",stdout); 23 register int i,j; 24 n=read(),faq=read(),m=read(); 25 for (i=1;i<=n;++i) a[i]=read(); 26 for (i=1;i<=m;++i){ 27 que[i].id=i, 28 que[i].l=read(),que[i].r=read(); 29 } 30 sort(que+1,que+m+1); 31 memset(b,0,sizeof(b));memset(p,0,sizeof(p)); 32 for (i=n;i>=1;i--) next[i]=p[a[i]],p[a[i]]=i; 33 for (i=1;i<=faq;i++) if (next[p[i]]) add(next[p[i]],1); 34 int L=1; 35 for (i=1;i<=m;i++){ 36 while (L<que[i].l){ 37 if (next[L]) add(next[L],-1); 38 if (next[next[L]]) add(next[next[L]],1); 39 L++; 40 } 41 an[que[i].id]=search(que[i].r)-search(que[i].l-1); 42 } 43 for (i=1;i<=m;i++) printf("%d\n",an[i]); 44 return 0; 45 }
BZOJ-2743: [HEOI2012]采花(樹狀數組 or TLE莫隊)