P4113 [HEOI2012]采花 (莫隊TLE)
阿新 • • 發佈:2018-07-21
pri dao printf 連續 愛好 const algorithm efi 整數
subtask1保證 \(n,m,c \leq 3*10^5\) ,占100分
subtask2保證 \(n,m,c \leq 2*10^6\) ,占100分畢竟Chen_Zhe還給了100分莫隊分
P4113 [HEOI2012]采花
題目描述
蕭薰兒是古國的公主,平時的一大愛好是采花。
今天天氣晴朗,陽光明媚,公主清晨便去了皇宮中新建的花園采花。
花園足夠大,容納了n朵花,花有c種顏色(用整數1-c表示),且花是排成一排的,以便於公主采花。公主每次采花後會統計采到的花的顏色數,顏色數越多她會越高興!同時,她有一癖好,她不允許最後自己采到的花中,某一顏色的花只有一朵。為此,公主每采一朵花,要麽此前已采到此顏色的花,要麽有相當正確的直覺告訴她,她必能再次采到此顏色的花。
由於時間關系,公主只能走過花園連續的一段進行采花,便讓女仆福涵潔安排行程。福涵潔綜合各種因素擬定了m個行程,然後一一向你詢問公主能采到多少朵花(她知道你是編程高手,定能快速給出答案!),最後會選擇令公主最高興的行程(為了拿到更多獎金!)。
輸入輸出格式
輸入格式:
第一行四個空格隔開的整數n、c以及m。接下來一行n個空格隔開的整數,每個數在[1, c]間,第i個數表示第i朵花的顏色。接下來m行每行兩個空格隔開的整數l和r(l ≤ r),表示女仆安排的行程為公主經過第l到第r朵花進行采花。
輸出格式:
共m行,每行一個整數,第i個數表示公主在女仆的第i個行程中能采到的花的顏色數。
輸入輸出樣例
輸入樣例#1:
5 3 5
1 2 2 3 1
1 5
1 2
2 2
2 3
3 5
輸出樣例#1:
2
0
0
1
說明
對於100%的數據,1 ≤ n ≤ \(2*10^6\) ,c ≤ n,m ≤ \(2*10^6\) 。
本題有兩個subtask
subtask1保證 \(n,m,c \leq 3*10^5\) ,占100分
subtask2保證 \(n,m,c \leq 2*10^6\) ,占100分
本題莫隊過不去,會TLE
但也是個不錯的莫隊練手題
畢竟Chen_Zhe還給了100分莫隊分 (還會給你小對勾)
#include <iostream> #include <cstdio> #include <cstring> #include <cmath> #include <algorithm> #define maxn 2000007 using namespace std; inline int read() { int x=0,f=1;char s=getchar(); while('0'>s||s>'9') { if(s=='-') f=-1; s=getchar(); } while('0'<=s&&s<='9') { x=x*10+s-'0'; s=getchar(); } return x*f; } int n,m,k,now; int a[maxn]; int belong[maxn]; int vis[maxn]; int ans[maxn]; struct node{ int l,r,id; }q[maxn]; inline bool cmp(const node &a,const node &b) { return belong[a.l]==belong[b.l] ? a.r<b.r : belong[a.l]<belong[b.l]; } inline void Add(int x) { vis[x]==1 ? ++now : now; ++vis[x]; } inline void Delet(int x) { vis[x]==2 ? --now : now; --vis[x]; } int main() { n=read(); int meiyongdebianliang_qidaotixingfanweidezuoye__233zhemechangdebianliangming=read(); m=read(); k=sqrt(n); for(int i=1;i<=n;++i) a[i]=read(); for(int i=1;i<=n;++i) belong[i]=(i-1)/k+1; for(int i=1;i<=m;++i) { q[i].l=read(); q[i].r=read(); q[i].id=i; } sort(q+1,q+1+m,cmp); int l=1,r=0; for(int i=1;i<=m;++i) { while(l > q[i].l) Add(a[--l]); while(l < q[i].l) Delet(a[l++]); while(r < q[i].r) Add(a[++r]); while(r > q[i].r) Delet(a[r--]); ans[q[i].id]=now; } for(int i=1;i<=m;++i) printf("%d\n",ans[i]); return 0; }
P4113 [HEOI2012]采花 (莫隊TLE)