# BZOJ 4241 历史研究（分块）

## 题解

 1 #include<iostream>
2 #include<cstring>
3 #include<cstdio>
4 #include<cmath>
5 #include<algorithm>
6 using namespace std;
7 const int N=100100;
8 int n,m,Block,block[N],a[N],b[N],cnt[400][N],top,stack[N],num[N];
9 long long f[400][N];
10 int main(){
11     scanf("%d%d",&n,&m);
12     Block=sqrt(n);
13     for(int i=1;i<=n;i++){
14         scanf("%d",&a[i]);
15         block[i]=(i-1)/Block+1;
16         b[i]=a[i];
17     }
18     sort(b+1,b+1+n);
19     int tot=unique(b+1,b+1+n)-b-1;
20     for(int i=1;i<=n;i++){
21         a[i]=lower_bound(b+1,b+1+tot,a[i])-b;
22     }
23     for(int i=1;i<=block[n];i++){
24         long long ans=0;
25         for(int j=lower_bound(block+1,block+1+n,i)-block;j<=n;j++){
26             cnt[i][a[j]]++;
27             ans=max(ans,(long long)cnt[i][a[j]]*b[a[j]]);
28             f[i][j]=ans;
29         }
30     }
31     for(int i=1;i<=m;i++){
32         top=0;
33         int x,y;
34         scanf("%d%d",&x,&y);
35         long long ans=f[block[x]+1][y];
36         int tmp=lower_bound(block+1,block+1+n,block[y])-block;
37         for(int j=tmp;j<=y;j++){
38             num[a[j]]++;
39             stack[++top]=a[j];
40         }
41         tmp=lower_bound(block+1,block+1+n,block[x]+1)-block;
42         for(int j=x;j<=tmp-1;j++){
43             num[a[j]]++;
44             ans=max(ans,(long long)(cnt[block[x]+1][a[j]]-cnt[block[y]][a[j]]+num[a[j]])*b[a[j]]);
45             stack[++top]=a[j];
46         }
47         printf("%lld\n",ans);
48         for(int j=1;j<=top;j++)num[stack[j]]=0;
49     }
50     return 0;
51 }

posted @ 2018-08-12 17:19  Xu-daxia  阅读(116)  评论(0编辑  收藏  举报