F题感觉自己想的很麻烦,双指针+dp,结果最后还是多亏了wls;
#include<bits/stdc++.h>
using namespace std;
const int N=2e5+10;
int a[N];
typedef long long LL;
void slove()
{
map<int,int>mp;
int n,k;
cin>>n>>k;
for(int i=0;i<n;i++)
{
int x;
cin>>x;
mp[x]++;
}
int ans=0,l=-1,r=-1,w=0;//ans是最大的区间长,也就是l-r的距离;
for(auto it : mp)
{
int x=it.first;
int y=it.second;
if(y<k)//不满足
{
l=-1,w=0;
}
else
{
if(x!=l+1)//有间断,连续距离置为0;
w=0;
w++;
if(w>ans)//更新最大连续距离
{
r=x;//更新右端点
ans=w;
}
l=x;
}
}
if(r==-1)
cout<<"-1"<<endl;
else
cout<<r-ans+1<<" "<<r<<endl;
}
int main()
{
int t;
cin>>t;
while(t--)
{
slove();
}
return 0;
}
H一开始没看出来其实就是求逆序对= =,既然是逆序对方法就多了,注意这里的逆序对可以是一组相同的数i<j,a[i]>=a[j];
这里我用了树状数组,分治(归并排序)也可以
#include<bits/stdc++.h>
using namespace std;
const int N=2e5+10;
typedef long long LL;
int a[N],c[N],n;
/*
抽象成统计逆序对,元素重复也算一组逆序对;
*/
struct node
{
int val;
int pos;
}nodes[N];
bool cmp(const node &n1,const node &n2)
{
if(n1.val==n2.val)//这里加个特判,元素重复就让位置大的排在前面;
return n1.pos>n2.pos;
return n1.val<n2.val;
}
int lowbit(int i)
{
return (-i)&i;
}
void add(int i,int v)
{
for(;i<=n;i+=lowbit(i))
c[i]+=v;
}
LL query(int i)
{
LL res=0;
for(;i>0;i-=lowbit(i))
res+=c[i];
return res;
}
int main()
{
int t;
cin>>t;
while(t--)
{
memset(a,0,sizeof a);
memset(nodes,0,sizeof nodes);
memset(c,0,sizeof c);
cin>>n;
for(int i=1;i<=n;i++)
{
cin>>nodes[i].val;
nodes[i].pos=i;
}
sort(nodes+1,nodes+1+n,cmp);
for(int i=1;i<=n;i++)
a[nodes[i].pos]=i;
LL cnt=0;
for(int i=1;i<=n;i++)
{
cnt+=i-1-query(a[i]);
add(a[i],1);
}
cout<<cnt<<endl;
}
return 0;
}