Title long and boring, but in fact the meaning of the questions is very simple.
A given length of \ (N \) a sequence \ (Q \) a query, each query corresponding to one interval of the original sequence. For each query interval, set the number \ (X_ {i} \) number in this range appears to \ (sum_ {X_ {i}} \) , we need to find the current range \ (X_ {i} * sum_ {X_ {i}} \ ) maximum.
Data range: \ (. 1 \ Leq N, Q \ ^ {leq10. 5},. 1 \ Leq the I X_ {} \ leq1. 9} {0 ^ \)
As we all know,For the unmodified range of inquiries and the data range (1e5 \) \ problem, we first consider the use of force to solve Mo, Mo fact, this question also can be used to solve the team, but it needs a little deformed.
After each block sorted inquiry, using Mo team algorithm. The original number sequence is discretized frequency and number of occurrences of each note is \ (Cnt_ {X} \) , the left subscript of the current team Mo \ (L \) and \ (R & lt \) , the current optimal answer as \ (SUM \) .
We found that when \ (l \) to reduce and \ (r \) case when the update increases good answer (that is, the original team of Mo \ (add \) operation, the corresponding deletion is \ (del \) ), only \ (R & lt Cnt_} ++ {\) , then find a maximum value \ (max (SUM, R & lt Cnt_ {}) \) .
But \ (del \) operation is difficult to achieve. If you remove the number corresponds to the maximum value, that is, \ (= Cnt_ {r} * X_ {r} \ sum) in, \ (X_ {r} - \) , then we can not guarantee the current \ (sum \) is the largest. I think on the test solution is to maintain a large time value, but can be found if you want to maintain the second largest value that need to maintain a third large value. . .
On the test segment tree author is used to solve this problem, the maintenance of each \ (Cnt_ {i} * X_ {i} \) a maximum value, corresponding to the time complexity is \ (O (n \ sqrt { n} log_ n-} {) \) . Although it is theoretically possible before, after the card is often indeed can live, but not perfectBecause I will not always card. Where it is a constant larger segment 40 of sleeve sub-tree code.
#include <iostream>
#include <cstdio>
#include <map>
#include <algorithm>
#include <cmath>
using namespace std;
#define LL long long
const int N=100020;
struct node {
LL p,sum;
node() {};
node(LL S,LL P) { p=P; sum=S; }
};
LL ans[N],maxx[N<<4],M2[N],n,m,A[N],T,cnt;
map<LL,LL> M1;
struct Qu {
int l,r,p;
bool operator < (const Qu &nxt) {//分块排序
if(l/T+1 != nxt.l/T+1) return l/T+1<nxt.l/T+1;
else return r<nxt.r;
}
}tzy[N];
void insert(int i,int l,int r,int x,int t) {//线段树维护
if(l==r) {
maxx[i]+=t;
return ;
}
int mid=(l+r)>>1;
if(x<=mid) insert(i<<1,l,mid,x,t);
else insert(i<<1|1,mid+1,r,x,t);
maxx[i]=max(maxx[i<<1],maxx[i<<1|1]);
}
void add(int now) {
insert(1,1,cnt,A[now],M2[A[now]]);
}
void del(int now) {
insert(1,1,cnt,A[now],-M2[A[now]]);
}
int main() {
cin>>n>>m; T=sqrt(n);
for(int i=1;i<=n;i++) {
scanf("%lld",&A[i]);
if(!M1[A[i]]) {
M1[A[i]]=++cnt;
M2[cnt]=A[i];
}
A[i]=M1[A[i]];
}
// cout<<endl<<cnt<<endl;
for(int i=1;i<=m;i++) {
scanf("%d%d",&tzy[i].l,&tzy[i].r);
tzy[i].p=i;
}
sort(tzy+1,tzy+1+m);
int l=1,r=1; insert(1,1,cnt,A[1],M2[A[1]]);
// for(int i=1;i<=m;i++) { cout<<tzy[i].l<<' '<<tzy[i].r<<endl;}
for(int i=1;i<=m;i++) {
while(r<tzy[i].r) add(++r);
while(l>tzy[i].l) add(--l);
while(r>tzy[i].r) del(r--);
while(l<tzy[i].l) del(l++);
ans[tzy[i].p]=maxx[1];
}
for(int i=1;i<=m;i++) cout<<ans[i]<<endl;
}
Another idea is actually that we can learn. If \ (del \) operations not realize, why we can not jump to optimize \ (del \) box operation, but rather to find ways to use only the problem into \ (add \) does it work?
So there will be some deformation algorithm Team Mo: Mo rollback team for poor maintenance \ (del \) where the operation, and its time complexity is very beautiful \ (O (n \ sqrt { n}) \ ) (not on a long and boring).
Mo rollback team can be said that the idea of block used in the extreme. We will issue a deal with a block of the block. Because we will ask the \ (r \) from small to large, so for processing the same block, you can ensure \ (r \) transfer is \ (O (n) \) , and only involves \ (add \) operation.
But \ (l \) just hard to deal with, because it is arranged compared to \ (r \) arrangement is disordered. But because it is the block arrangement, we can ensure that the right end point of the current block is \ (R_ {I} \) , the \ (L \) , at most \ (\ sqrt {n} \ ) step.
So we can consider such a strategy. Each treatment are \ (L \) Move \ (R_ {I} \) , it can guarantee \ (L \) and \ (R & lt \) are both \ (the Add \) operation. The current inquiry has been dealt with, simply \ (L \) "roll" back. Since \ (L \) was transferred up to \ (\ sqrt {n} \ ) times, \ (R & lt \) transferring most \ (n-\) times, so complexity is \ (O (n \ sqrt { n} ) \) .
Thinking finished, but there are special circumstances seed treatment, when \ (L_ {i} \ leq l, r \ leq R_ {i} \) , the current interrogation is about endpoints in the above-described method of using a block at the same time not a good deal. Because you can guarantee \ (RL \ Leq \ sqrt {the n-} \) , you only need to run side to violence.
More detail, as detailed in the code.
#include <iostream>
#include <cstdio>
#include <map>
#include <algorithm>
#include <cstring>
#include <cmath>
using namespace std;
#define LL long long
const int N=100020;
LL ans[N],B[N],q,cnt[N],block[N],L[N],R[N],Cntl,n,sum,m,p,A[N],T;
struct Qu {
int l,r,p;
bool operator < (const Qu &nxt) {
return block[l]==block[nxt.l] ? r<nxt.r:l<nxt.l;
}
}tzy[N];
void divide() {
for(int i=1;i<=q;i++) L[i]=R[i-1]+1,R[i]=L[i]+T-1;
if(R[q]<n) L[q+1]=R[q]+1,R[q+1]=n,q++;
for(int i=1;i<=n;i++) block[i]=(i-1)/T+1;
}
void add(int x) {
cnt[A[x]]++;
if(cnt[A[x]]*B[A[x]]>sum) sum=cnt[A[x]]*B[A[x]];
}
LL solve(int l,int r) {
static int c[N];
LL solu=0;
for(int i=l;i<=r;i++) ++c[A[i]];
for(int i=l;i<=r;i++) solu=max(solu,c[A[i]]*B[A[i]]);
for(int i=l;i<=r;i++) --c[A[i]];
return solu;
}
int main() {
cin>>n>>m; T=sqrt(n); q=n/T;
for(int i=1;i<=n;i++) scanf("%lld",&A[i]),B[i]=A[i];
for(int i=1;i<=m;i++) scanf("%d%d",&tzy[i].l,&tzy[i].r),tzy[i].p=i;
sort(B+1,B+1+n);
p=unique(B+1,B+1+n)-B-1;
// cout<<endl<<cnt<<endl;
for(int i=1;i<=n;i++) A[i]=lower_bound(B+1,B+1+p,A[i])-B;
divide();
sort(tzy+1,tzy+1+m);
for(int i=1,l,r,j=1;i<=q;i++) {
r=R[i]; sum=0;
memset(cnt,0,sizeof(cnt));
while(block[tzy[j].l]==i) {
l=R[i]+1;
if(tzy[j].r-tzy[j].l<=T)
ans[tzy[j].p]=solve(tzy[j].l,tzy[j].r),++j;
else {
while(r<tzy[j].r) add(++r);
LL tmp=sum;
while(l>tzy[j].l) add(--l);
ans[tzy[j].p]=sum;
sum=tmp;
while(l<=R[i]) --cnt[A[l++]];
++j;
}
}
}
for(int i=1;i<=m;i++) printf("%lld\n",ans[i]);
}
Continue
There is also a test for each node \ (4 * 4 \) title of the matrix did not write. For me this kind of more of a month, write a blog to be a morning person. . . It's still early