crf 的数数 (树状数组 离线操作)
2017-09-11 15:41
204 查看
crf 的数数
9.370分 莫队
#include<iostream> #include<cstdio> #include<algorithm> #include<cmath> #define N 1000010 #define LL long long using namespace std; int n, q, place , a ; int cnt , ans; inline int read(){ int x=0,f=1; char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} return x*f; } struct data{ int l, r, id; LL res; }que ; bool cmp(data a, data b){ if(place[a.l] == place[b.l]) return a.r < b.r; return a.l < b.l; } bool recmp(data a, data b){ return a.id < b.id; } void update(int pos, int add){ cnt[a[pos]] += add; if(cnt[a[pos]]-add == a[pos]) ans--; if(cnt[a[pos]] == a[pos]) ans++; } void solve(){ for(register int i=1,l=1,r=0; i<=q; i++){ for( ; r<que[i].r; r++) update(r+1, 1); for( ; r>que[i].r; r--) update(r, -1); for( ; l<que[i].l; l++) update(l, -1); for( ; l>que[i].l; l--) update(l-1, 1); /*if(que[i].l == que[i].r){ que[i].a = 0; continue; }*/ que[i].res = ans; } } int main(){ freopen ("count.in", "r", stdin); freopen ("count.out", "w", stdout); n = read(); q = read(); for(register int i=1; i<=n; i++) a[i] = read(); int block = int(sqrt(n)); for(register int i=1; i<=n; i++) place[i] = (i-1) / block + 1; for(register int i=1; i<=q; i++){ que[i].l = read(), que[i].r = read(); que[i].id = i; } sort(que+1, que+q+1, cmp); solve(); sort(que+1, que+q+1, recmp); for(register int i=1; i<=q; i++) printf("%d\n", que[i].res); return 0; }
100分 树状数组
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> using namespace std; template<class T>inline void read(T &res) { static char ch; T flag=1; while((ch=getchar())<'0'||ch>'9')if(ch=='-')flag=-1; res=ch-48; while((ch=getchar())>='0'&&ch<='9')res=res*10+ch-48; res*=flag; } const int N = 1000010; const int Q = 1000010; struct DATUM { int x, y, delta; bool operator<(const DATUM &rhs) const { if(x!=rhs.x) return x<rhs.x; if(y!=rhs.y) return y<rhs.y; if(delta!=rhs.delta) return delta<rhs.delta; } } data[N*4+Q]; int tot, ans[Q]; int n, q, a ; inline void addD(int x, int y, int delta) { data[++tot] = (DATUM){x, y, delta};} void add(int pos, int val) { for(int x=pos; x<=n; x+=x&-x) a[x] += val;} int query(int pos) {int val=0; for(int x=pos; x; x-=x&-x) val += a[x]; return val;} pair<int, int> aa ; int main() { freopen("count.in", "r", stdin); freopen("count.out", "w", stdout); read(n); read(q); for(register int i=1; i<=n; i++) read(aa[i].first), aa[i].second = i; sort(aa+1, aa+n+1);//按照first排序 int siz = 0; for(register int i=1; i<=n; i++) { if(aa[i].first == aa[i-1].first) siz++; else siz = 2, aa[i-siz+1].second = 0; if(siz > aa[i].first) { addD(aa[i-aa[i].first].second+1, aa[i].second, +1); addD(aa[i-aa[i].first+1].second+1, aa[i].second, -1); if(siz > aa[i].first + 1) addD(aa[i-aa[i].first-1].second+1, aa[i].second, -1); if(siz > aa[i].first + 1) addD(aa[i-aa[i].first].second+1, aa[i].second, +1); } } for(register int i=1,l,r; i<=q; i++) read(l), read(r), addD(l, r, i+1); sort(data+1, data+tot+1); for(register int i=1; i<=tot; i++) { if(data[i].delta <= 1) add(data[i].y, data[i].delta); else if(data[i].y>=1 && data[i].y<=n) ans[data[i].delta-1] = query(data[i].y); } for(register int i=1; i<=q; i++) printf("%d\n", ans[i]); return 0; }
相关文章推荐
- HDU 3874 Necklace(树状数组的离线操作)
- HDU 3874 Necklace(树状数组的离线操作)
- bzoj 1878 SDOI2009树状数组 离线操作
- hdu 3874 Necklace 树状数组 离线操作
- hdu-4638-Group-(树状数组,离线操作)
- hdu 4630 No Pain No Game(树状数组离线操作)
- SPOJ3267--D-query (树状数组离线操作)
- hdu 3333(树状数组 + 离线操作)
- Codeforces Round #365 (Div. 2) D. Mishka and Interesting sum 离线操作,树状数组,last[value],异或和
- HDU 4358 Boring counting(树状数组离线操作+欧拉序列)
- hdu 3333 Turing Tree(树状数组离线操作)
- 【莫队 or 离线+树状数组】BZOJ1878(SDOI2009)[HH的项链]题解
- POJ 2309 BST 树状数组基本操作
- HDU 3333 Turing Tree 树状数组 离线查询
- spoj D-query 区间不同数个数 主席树||离线+树状数组
- CF #365 (Div. 2) D - Mishka and Interesting sum 离线树状数组
- 树状数组区间操作模板
- [SPOJ DQUERY] D-query(树状数组,离线)
- HDU 4417 Super Mario(离线线段树or树状数组)
- HDU 4417 —— Super Mario(树状数组,离散化,离线处理)