Codeforces Round #790 div4补题(F,H)

F题感觉自己想的很麻烦,双指针+dp,结果最后还是多亏了wls;

#include
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=a[j];
这里我用了树状数组,分治(归并排序)也可以

#include
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;
}

你可能感兴趣的:(Codeforces,算法)