BZOJ 2743: [HEOI2012]采花 [树状数组 | 主席树]
题意:
查询区间中出现次数$>2$的颜色个数
一眼主席树,区间中$l \le last[i] \le r$的个数减去$l \le last[last[i]] \le r$的个数,搞两颗主席树来做
然后就T了
因为bzoj上数据是1e6....
还是离线树状数组吧....
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> using namespace std; #define lc(x) t[x].l #define rc(x) t[x].r const int N=1e6+5; inline int read(){ char c=getchar();int x=0,f=1; while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();} while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();} return x*f; } int n, k, Q, a[N], last[N], pos[N], l, r; struct ChairTree{ struct meow{int l, r, sum;} t[N*20]; int sz, root[N]; void ins(int &x, int l, int r, int p) { t[++sz] = t[x]; x=sz; t[x].sum++; if(l==r) return; int mid = (l+r)>>1; if(p<=mid) ins(t[x].l, l, mid, p); else ins(t[x].r, mid+1, r, p); } int que(int x, int y, int l, int r, int ql, int qr) { if(ql<=l && r<=qr) return t[y].sum - t[x].sum; else { int mid=(l+r)>>1, ans=0; if(ql<=mid) ans += que(lc(x), lc(y), l, mid, ql, qr); if(mid<qr) ans += que(rc(x), rc(y), mid+1, r, ql, qr); return ans; } } }C1, C2; int main() { freopen("in","r",stdin); n=read(); k=read(); Q=read(); for(int i=1; i<=n; i++) a[i]=read(), last[i] = pos[a[i]], pos[a[i]] = i; for(int i=1; i<=n; i++) { C1.root[i] = C1.root[i-1], C1.ins(C1.root[i], 0, n, last[i]); C2.root[i] = C2.root[i-1], C2.ins(C2.root[i], 0, n, last[last[i]]); } for(int i=1; i<=Q; i++) l=read(), r=read(), printf("%d\n", C1.que(C1.root[l-1], C1.root[r], 0, n, l, r) - C2.que(C2.root[l-1], C2.root[r], 0, n, l, r) ); }
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> using namespace std; #define lc(x) t[x].l #define rc(x) t[x].r const int N=1e6+5; inline int read(){ char c=getchar();int x=0,f=1; while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();} while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();} return x*f; } int n, k, Q, a[N], last[N], pos[N], l, r; int c[N]; inline void add(int p, int v) {if(p!=0) for(;p<=n;p+=(p&-p)) c[p]+=v;} inline int sum(int p) {int ans=0; for(;p;p-=(p&-p)) ans+=c[p]; return ans;} struct meow{ int l, r, qid; bool operator <(const meow &a) const {return r<a.r;} }q[N]; int ans[N], now; int main() { freopen("in","r",stdin); n=read(); k=read(); Q=read(); for(int i=1; i<=n; i++) a[i]=read(); for(int i=1; i<=Q; i++) l=read(), r=read(), q[i]=(meow){l, r, i}; sort(q+1, q+1+Q); now = 1; for(int i=1; i<=n; i++) { last[i] = pos[a[i]]; pos[a[i]] = i; add(last[i], 1); add(last[last[i]], -1); while(q[now].r == i) ans[q[now].qid] = sum(i) - sum(q[now].l-1), now++; } for(int i=1; i<=Q; i++) printf("%d\n", ans[i]); }
Copyright:http://www.cnblogs.com/candy99/