求存在绝对众数的子区间的个数
这也是前几天hdu出过的题
感觉具体内容自己有点讲不清楚
可以推荐这两篇博客:
#pragma GCC optimize(2)
#pragma GCC optimize(3,"Ofast","inline")
#include <bits/stdc++.h>
#define inf 0x7fffffff
#define ll long long
#define int long long
//#define double long double
#define re int
#define void inline void
#define eps 1e-8
//#define mod 1e9+7
#define ls(p) p<<1
#define rs(p) p<<1|1
#define pi acos(-1.0)
#define pb push_back
#define P pair < int , int >
#define mk make_pair
using namespace std;
const int mod=1e9+7;
const int M=1e8+5;
const int N=1e6+5;//?????????? 4e8
struct node
{
int l,r,add,sum,val;
}e[N*4];
void push(int p)
{
e[p].sum=e[ls(p)].sum+e[rs(p)].sum;
e[p].val=e[ls(p)].val+e[rs(p)].val;
}
void bulid(int p,int l,int r)
{
e[p].l=l,e[p].r=r;
e[p].add=e[p].sum=e[p].val=0;
if(l==r) return;
int mid=(l+r)>>1;
bulid(ls(p),l,mid);bulid(rs(p),mid+1,r);
}
void spread(int p)
{
if(e[p].l==e[p].r) return;
if(e[p].add)
{
e[ls(p)].sum+=(e[ls(p)].r-e[ls(p)].l+1)*e[p].add;
e[rs(p)].sum+=(e[rs(p)].r-e[rs(p)].l+1)*e[p].add;
e[ls(p)].val+=(e[ls(p)].r+e[ls(p)].l)*(e[ls(p)].r-e[ls(p)].l+1)/2*e[p].add;//
e[rs(p)].val+=(e[rs(p)].r+e[rs(p)].l)*(e[rs(p)].r-e[rs(p)].l+1)/2*e[p].add;//
e[ls(p)].add+=e[p].add;
e[rs(p)].add+=e[p].add;
e[p].add=0;
}
}
void change(int p,int l,int r,int d)
{
if(l<=e[p].l&&e[p].r<=r)
{
e[p].sum+=(e[p].r-e[p].l+1)*d;
e[p].val+=(e[p].r+e[p].l)*(e[p].r-e[p].l+1)/2*d;
e[p].add+=d;
return;
}
spread(p);
int mid=(e[p].l+e[p].r)>>1;
if(l<=mid) change(ls(p),l,r,d);
if(mid<r) change(rs(p),l,r,d);
push(p);
}
int ask(int p,int l,int r)
{
if(l<=e[p].l&&e[p].r<=r) return e[p].sum;
spread(p);
int mid=(e[p].l+e[p].r)>>1;
int ans=0;
if(l<=mid) ans+=ask(ls(p),l,r);
if(mid<r) ans+=ask(rs(p),l,r);
return ans;
}
int ask1(int p,int l,int r)
{
if(l<=e[p].l&&e[p].r<=r) return e[p].val;
spread(p);
int mid=(e[p].l+e[p].r)>>1;
int ans=0;
if(l<=mid) ans+=ask1(ls(p),l,r);
if(mid<r) ans+=ask1(rs(p),l,r);
return ans;
}
int a[N],b[N];
void solve()
{
int ans=0;
vector < int > v[N];
int n,m,q;
cin>>n;
for(re i=1;i<=n;i++) scanf("%lld",&a[i]),b[i]=a[i];
sort(b+1,b+n+1);m=unique(b+1,b+n+1)-(b+1);
for(re i=1;i<=n;i++) a[i]=lower_bound(b+1,b+m+1,a[i])-b;
bulid(1,1,2*n);change(1,n,n,1);
for(re i=1;i<=n;i++) v[a[i]].pb(i);
for(re i=1;i<=m;i++)
{
v[i].pb(n+1);
int last=0,lastn=0;
int sz=v[i].size();
for(re j=0;j<sz;j++)
{
int L=v[i][j]-last-1;
int l=lastn-L;
int r=lastn-1;
if(v[i][j]!=last+1)
{
ans+=L*ask(1,1,l+n-1);
ans+=(r+n)*ask(1,l+n,r+n);
ans-=ask1(1,l+n,r+n);
change(1,l+n,r+n,1);
}
if(v[i][j]==n+1) continue;
ans+=ask(1,1,l+n);
change(1,l+n+1,l+n+1,1);
last=v[i][j];lastn=l+1;
}
last=0,lastn=0;
for(re j=0;j<sz;j++)
{
int L=v[i][j]-last-1;
int l=lastn-L;
int r=lastn-1;
if(v[i][j]!=last+1) change(1,l+n,r+n,-1);
if(v[i][j]==n+1) continue;
change(1,l+1+n,l+1+n,-1);
last=v[i][j];lastn=l+1;
}
}
cout<<ans<<endl;
}
signed main()
{
int T=1;
cin>>T;
for(int index=1;index<=T;index++)
{
// printf("Case %d:\n",index);
solve();
// puts("");
}
return 0;
}
/*
1
6 5
0 0 0 122 499 8888
*/