First with the MO team algorithm to ensure the complexity of the transfer between inquiries, each transfer requires O (sqrt (m)) insertion and deletion, the weight of the block insertion/deletion is O (1).
Then ask the time with the weight of the block query interval k small value, each time is O (sqrt (n)).
So the total complexity is O (m* (sqrt (n) +sqrt (m)).
The constants are very small.
Other data structures that are maintained by weight cannot be inserted and removed by O (1).
poj2104 output optimization do not forget to handle negative numbers.
After the chairman of the tree, this code is currently Rank1on poj2761.
rank |
run ID |
user |
memory< /th> |
time |
language |
code Length |
Submit time |
1 |
13702017 (2) |
lizitong |
4056k |
579MS |
g++ |
2455B |
2014-12-10 13:00:22 |
#include <cstdio> #include <algorithm> #include <cmath>using namespace Std;int num,ch[12],f,c;inline void R (int &x) {c=0;f=1; for (;c< ' 0 ' | | C> ' 9 '; C=getchar ()) if (c== '-') f=-1; for (x=0;c>= ' 0 ' &&c<= ' 9 '; C=getchar ()) (x*=10) + = (c ' 0 '); X*=f;} inline void P (int x) {if (x<10) putchar (x+ ' 0 '); Else{p (X/10);p Utchar (x%10+ ' 0 ');}} struct Point{int v,p;} T[100001];struct ask{int l,r,k,p;} Q[5001];int N,m,a[100001],ma[100001],en,num[100001],num2[100001];int L[330],r[330],sumv[330],b[100001],sum=1, Anss[5001];bool operator < (const point &a,const point &b) {return A.V<B.V;} BOOL operator < (const ask &a,const ask &b) {return NUM2[A.L]!=NUM2[B.L]? NUM2[A.L]<NUM2[B.L]: A.R<B.R;} void Mo_make_block () {int sum=1,sz=sqrt (n); if (!sz) sz=1;for (; sum*sz<n;++sum) {int r=sum*sz; for (int i= (sum-1) *sz+1;i<=r;++i) num2[i]=sum; }for (int i= (sum-1) *sz+1;i<=n;++i) num2[i]=sum;} void Val_make_block () {int sz=sqrt (en), if (!sz) sz=1;for (;Sum*sz<en;++sum) {l[sum]=r[sum-1]+1; r[sum]=sum*sz; for (int i=l[sum];i<=r[sum];++i) num[i]=sum; }l[sum]=r[sum-1]+1; r[sum]=en;for (int i=l[sum];i<=r[sum];++i) num[i]=sum;} void Insert (const int &x) {++b[x]; ++sumv[num[x]];} void Delete (const int &x) {--b[x];--sumv[num[x]];} int Kth (const int &x) {int cnt=0; for (int i=1;; i++) {Cnt+=sumv[i]; if (cnt>=x) {cnt-=sumv[i]; for (int j=l[i];; J + +) {Cnt+=b[j]; if (cnt>=x) return J;} }}}int Main () {R (n); R (M); for (int i=1;i<=n;++i) {R (T[I].V); t[i].p=i;} Sort (t+1,t+n+1); ma[a[t[1].p]=++en]=t[1].v;for (int i=2;i<=n;++i) {if (T[I].V!=T[I-1].V) ++en; MA[A[T[I].P]=EN]=T[I].V; }val_make_block (); for (int i=1;i<=m;++i) {R (Q[I].L); R (Q[I].R); R (Q[I].K); Q[i].p=i; }mo_make_block (); sort (q+1,q+m+1); for (int i=q[1].l;i<=q[1].r;++i) Insert (A[i]); Anss[q[1].p]=ma[kth (Q[1].K)]; for (int i=2;i<=m;++i) {if (Q[I].L<Q[I-1].L) for (iNT J=q[i-1].l-1;j>=q[i].l;--j) Insert (A[j]); else for (int j=q[i-1].l;j<q[i].l;++j) Delete (A[j]); if (Q[I].R<Q[I-1].R) for (int j=q[i-1].r;j>q[i].r;--j) Delete (A[j]); else for (int j=q[i-1].r+1;j<=q[i].r;++j) Insert (A[j]); Anss[q[i].p]=ma[kth (Q[I].K)]; } for (int i=1;i<=m;++i) P (Anss[i]), puts (""); return 0;}
"Mo Team Algorithm" "Weight value chunking" poj2104 k-th number/poj2761 Feed the Dogs