BZOJ3236 [Ahoi2013]作业 【莫队 + 树状数组】
2018-05-16 08:31
375 查看
题目链接
题解
没想到这题真的是如此暴力
#include<algorithm> #include<iostream> #include<cstring> #include<cstdio> #include<cmath> #include<map> #define Redge(u) for (int k = h[u],to; k; k = ed[k].nxt) #define REP(i,n) for (int i = 1; i <= (n); i++) #define mp(a,b) make_pair<int,int>(a,b) #define cls(s) memset(s,0,sizeof(s)) #define cp pair<int,int> #define LL long long int #define lbt(x) (x & -x) using namespace std; const int maxn = 100005,maxm = 3000005,INF = 1000000000; inline int read(){ int out = 0,flag = 1; char c = getchar(); while (c < 48 || c > 57){if (c == '-') flag = -1; c = getchar();} while (c >= 48 && c <= 57){out = (out << 3) + (out << 1) + c - 48; c = getchar();} return out * flag; } int n,m,a[maxm],b[maxm],bi,B,tot,ans1[maxm],ans2[maxm]; struct Que{int l,r,a,b,bl,id;}q[maxm]; inline bool operator <(const Que& a,const Que& b){ return a.bl == b.bl ? a.r < b.r : a.l < b.l; } int getn(int x){return lower_bound(b + 1,b + 1 + tot,x) - b;} int bac[maxm]; struct BIT{ int s[maxm]; void add(int u,int v){while (u <= tot) s[u] += v,u += lbt(u);} int query(int u){int re = 0; while (u) re += s[u],u -= lbt(u); return re;} int sum(int l,int r){return query(r) - query(l - 1);} }T1,T2; void solve(){ sort(q + 1,q + 1 + m); int L = q[1].l,R = q[1].r; for (int i = L; i <= R; i++){ T1.add(a[i],1); if (!bac[a[i]]) T2.add(a[i],1); bac[a[i]]++; } ans1[q[1].id] = T1.sum(q[1].a,q[1].b); ans2[q[1].id] = T2.sum(q[1].a,q[1].b); for (int i = 2; i <= m; i++){ while (L != q[i].l || R != q[i].r){ if (L < q[i].l){ bac[a[L]]--; T1.add(a[L],-1); if (!bac[a[L]]) T2.add(a[L],-1); L++; } if (L > q[i].l){ L--; T1.add(a[L],1); if (!bac[a[L]]) T2.add(a[L],1); bac[a[L]]++; } if (R < q[i].r){ R++; T1.add(a[R],1); if (!bac[a[R]]) T2.add(a[R],1); bac[a[R]]++; } if (R > q[i].r){ bac[a[R]]--; T1.add(a[R],-1); if (!bac[a[R]]) T2.add(a[R],-1); R--; } } ans1[q[i].id] = T1.sum(q[i].a,q[i].b); ans2[q[i].id] = T2.sum(q[i].a,q[i].b); } for (int i = 1; i <= m; i++) printf("%d %d\n",ans1[i],ans2[i]); } int main(){ n = read(); m = read(); B = (int)sqrt(n) + 1; REP(i,n) a[i] = b[++bi] = read(); REP(i,m){ q[i].l = read(); q[i].r = read(); q[i].bl = q[i].l / B; b[++bi] = q[i].a = read(); b[++bi] = q[i].b = read(); q[i].id = i; } sort(b + 1,b + 1 + bi); tot = 1; for (int i = 2; i <= bi; i++) if (b[i] != b[tot]) b[++tot] = b[i]; for (int i = 1; i <= n; i++) a[i] = getn(a[i]); for (int i = 1; i <= m; i++) q[i].a = getn(q[i].a),q[i].b = getn(q[i].b); solve(); return 0; }
相关文章推荐
- [ 莫队 树状数组 ] [ AHOI2013 ] BZOJ3236
- 【BZOJ3809/3236】Gty的二逼妹子序列 [Ahoi2013]作业 莫队算法+分块
- [BZOJ3236][Ahoi2013]作业(莫队+分块)
- BZOJ3236: [Ahoi2013]作业 莫队+分块
- COGS.1822.[AHOI2013]作业(莫队 树状数组/分块)
- [BZOJ 3236] [Ahoi2013] 作业 && [BZOJ 3809] 【莫队(+分块)】
- Bzoj 3236: [Ahoi2013]作业 莫队,分块
- [BZOJ3236][Ahoi2013]作业(莫队+树状数组)
- BZOJ 3236: [Ahoi2013]作业|莫队算法|树状数组
- 【莫队算法】【权值分块】bzoj3236 [Ahoi2013]作业
- bzoj 3236: [Ahoi2013]作业 (莫队+分块)
- BZOJ 3236: [Ahoi2013]作业( 莫队 + BIT )
- BZOJ_3809_Gty的二逼妹子序列 && BZOJ_3236_[Ahoi2013]作业 _莫队+分块
- bzoj 3236: [Ahoi2013]作业 莫队算法+分块
- 莫队+分块+树状数组 【Ahoi2013】 作业 bzoj3236
- BZOJ 3809: Gty的二逼妹子序列 & 3236: [Ahoi2013]作业 [莫队]
- [bzoj3236][Ahoi2013]作业(莫队+树状数组)
- 【BZOJ】【P3236】【Ahoi2013】【作业】【题解】【莫队】
- 【树套树】【bzoj 3236】: [Ahoi2013]作业
- 【BZOJ 3236】 [Ahoi2013]作业