问题在于怎么抽象出矩形面积。。。
求某个数数量恰好是time的子区间个数
当两个点c和d都是a1且两点之间的a1数量等于time时那左端点可以是c之前的且不是a1的那个点的任意一点,右端点可以是d之后的且不是a1的任何一点,那左端点可以移动的左右范围当做矩形长的左右端点的x值,右端点可以移动的左右范围当做矩形长的上下端点的y值这就是个矩形了。。。然后求总面积
#include<cstdio>
#include<algorithm>
#include<iostream>
#include<vector>
#include<cstring>
#define maxn 100005
#define lson i<<1
#define rson (i<<1)+1
#define LL long long
using namespace std;
int a[maxn],b[maxn],time,n,l;
int len[maxn*4],cnt[maxn*4];
vector<int>ve[maxn];
struct line{
int x1,x2,y,flag;
line(){};
line(int a,int b,int c,int d):x1(a),x2(b),y(c),flag(d){};
}lin[maxn*4];
void pushUp(int i,int l,int r)
{
if(cnt[i])len[i] = r-l+1;
else {
if(l==r)len[i] = 0;
else len[i] = len[lson]+len[rson];
}
}
void update(int i,int l,int r,int L,int R,int flag)
{
if(l==L&&r==R)
{
cnt[i]+=flag;
pushUp(i,l,r);
return ;
}
int mid = (l+r)/2;
if(L>mid) update(rson,mid+1,r,L,R,flag);
else if(R<=mid) update(lson,l,mid,L,R,flag);
else {
update(rson,mid+1,r,mid+1,R,flag);
update(lson,l,mid,L,mid,flag);
}
pushUp(i,l,r);
}
bool cmp(line l1,line l2)
{
return l1.y<l2.y;
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
scanf("%d%d",&n,&time);
l = 0;
for(int i=0;i<n;i++)scanf("%d",&a[i]),b[i] = a[i];
memset(len,0,sizeof(len));
memset(cnt,0,sizeof(cnt));
sort(b,b+n);
int am = unique(b,b+n)-b;
for(int i=0;i<am;i++)
ve[i].clear();
for(int i=0;i<n;i++)
{
int pre = lower_bound(b,b+am,a[i])-b;
ve[pre].push_back(i);
}
for(int i=0;i<am;i++)
for(int j=0;j+time-1<ve[i].size();j++)
{
lin[l++] = line(j?ve[i][j-1]+1:0,ve[i][j],ve[i][j+time-1],1);
lin[l++] = line(j?ve[i][j-1]+1:0,ve[i][j],(j+time<ve[i].size()?ve[i][j+time]-1:n-1)+1,-1);
}
sort(lin,lin+l,cmp);
LL ans = 0;
for(int i=0;i<l-1;i++)
{
update(1,0,n-1,lin[i].x1,lin[i].x2,lin[i].flag);
ans = ans + ((LL)lin[i+1].y-lin[i].y)*len[1];
}
printf("%I64d\n",ans);
}
return 0;
}