Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 2592 Accepted Submission(s): 884
/* hdu3333 题意:给你一段很长的数字,求区间[l,r]里的和,满足数字重复出现的,只能算一次。 测试数据10组, N 30000; 数字大小10^9;Q 10^5; 用数组保存要询问的区间,离线算法.. Next[]求出下一个重复出现数字的位置 对x排序,用线段树更新max值。 对初始的询问位置排序,输出结果。 */ #include<cstdio> #include<iostream> #include<cstdlib> #include<algorithm> #include<map> using namespace std; struct st { int l; int r; __int64 max; }f[30003*4]; struct node { int begin; int end; __int64 max; int wz; }b[100003]; int a[30003]; int tom[30003]; int Next[30003]; map<int,int>hxl; bool cmp1(node n1,node n2) //起始位置从小到大排 { return n1.begin<n2.begin; } bool cmp2(node n1,node n2) //back { return n1.wz<n2.wz; } void build(int l,int r,int n) { int mid=(l+r)/2; f[n].l=l; f[n].r=r; if(l==r) { f[n].max=tom[l]; return; } build(l,mid,n*2); build(mid+1,r,n*2+1); f[n].max=f[n*2].max+f[n*2+1].max; } void update(int wz,int num,int n) { int mid=(f[n].l+f[n].r)/2; if(f[n].l==wz && f[n].r==wz) { f[n].max=num; return; } if(mid>=wz) update(wz,num,n*2); else if(mid<wz) update(wz,num,n*2+1); f[n].max=f[n*2].max+f[n*2+1].max; } __int64 query(int l,int r,int n) { int mid=(f[n].l+f[n].r)/2; if(f[n].l==l && f[n].r==r) { return f[n].max; } if(mid>=r) return query(l,r,n*2); else if(mid<l) return query(l,r,n*2+1); else { return query(l,mid,n*2)+query(mid+1,r,n*2+1); } } void make_then(int N,int Q) { int i,j,k; for(i=1;i<=N;i++) { tom[i]=0; Next[i]=0; } hxl.clear(); for(i=N;i>=1;i--) { k=a[i]; if(hxl.find(k)==hxl.end()) { hxl[k]=i; } else { Next[i]=hxl[k]; hxl[k]=i; } }// get Next[] hxl.clear(); for(i=1;i<=N;i++) { k=a[i]; if(hxl.find(k)==hxl.end()) { tom[i]=k; hxl[k]=i; } }// get tom[] } void cs(int N,int Q) { int i,j; for(i=1;i<=N;i++) printf("%d ",Next[i]); printf("\n\n"); for(i=1;i<=N;i++) printf("%d ",tom[i]); printf("\n"); } void make_ini() { int Q,N,i,j,k,l,r; scanf("%d",&N); for(i=1;i<=N;i++) scanf("%d",&a[i]); scanf("%d",&Q); for(i=1;i<=Q;i++) { scanf("%d%d",&b[i].begin,&b[i].end); b[i].wz=i; b[i].max=0; } sort(b+1,b+1+Q,cmp1); make_then(N,Q); // cs(N,Q); build(1,N,1); k=1; for(i=1;i<=Q;i++) { l=b[i].begin; r=b[i].end; if(k<l) { for(j=k;j<l;j++) { if(Next[j]>0) update(Next[j],a[j],1); } k=l; } b[i].max=query(l,r,1); } sort(b+1,b+1+Q,cmp2); for(i=1;i<=Q;i++) printf("%I64d\n",b[i].max); } int main() { int T; scanf("%d",&T); { while(T--) { make_ini(); } } return 0; }