先上题目:https://www.luogu.org/problemnew/show/P1309
拿到这个题目,我不屑一顾,暴力搞搞就完事了,直到看到数据范围,我才对着电脑思考了好久...
暴力搞一波的复杂度大概是O(r*n*logn)的,怀着侥幸的心理,果然T了四组数据。
下面是题解,表达能力有限,大概只有我自己能看懂(大概只有我自己才会看这篇博客吧)
1.首先按每个人的s和编号,sort一遍。
2.第一步sort了之后的数组是有序的了,那么接下来的操作都是在有序的基础上进行的(大家应该知道归并排序,这个不就是个归并的过程嘛)。每一次比赛,都将赢得和输得人分别存在twin和tlose中,然后直接归并,twin和tlose都是有序的(原本是有序的,s++和不加,拿到分别的twin和tlose中都是有序的),所以复杂度就从O(nlogn)降到了O(n)。整体复杂度从O(r*n*logn)降到了大概O(r*n),(但是第一次还是有一个sort,我没算进去。)
下面是代码:
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 2e5+7;
struct node
{
ll s;
ll w;
int q;
}Q[maxn],twin[maxn],tlose[maxn];
bool cmp(node a,node b)
{
if(a.s==b.s)
{
return a.q<b.q;
}
return a.s>b.s;
}
int main()
{
int n,r,rk;
while(~scanf("%d%d%d",&n,&r,&rk))
{
for(int i=1;i<=2*n;i++)
{
Q[i].q = i;
scanf("%lld",&Q[i].s);
}
for(int i=1;i<=2*n;i++)
{
scanf("%lld",&Q[i].w);
}
sort(Q+1,Q+1+2*n,cmp);
for(int k=0;k<r;k++)
{
int pw = 0,pl = 0;
for(int i=1;i<2*n;i+=2)
{
if(Q[i].w>Q[i+1].w)
{
Q[i].s++;
twin[++pw] = Q[i];
tlose[++pl] = Q[i+1];
}
else
{
Q[i+1].s++;
twin[++pw] = Q[i+1];
tlose[++pl] = Q[i];
}
}
merge(twin+1,twin+1+pw,tlose+1,tlose+1+pl,Q+1,cmp);
}
cout<<Q[rk].q<<endl;
}
return 0;
}
因本菜鸡太懒了,太蒻了,所以,讲解不仅逻辑不清而且题目还很简单。
PS:(这是本蒻鸡的第一篇题解,希望以后可以坚持下去,碰见好的题目一定尽量都发来)
PPS:忘了一件重要的事情,STL的merge的用法是:前面给俩个数组的迭代器,然后传一个数组的开头,最后跟一个cmp(vector也一样)。