数据结构好题#1.1
看了眼题解,有很多种多样的算法。有平衡树,set,线段树,并查集,链表的。实在是过于百花齐放
也有跟我用一个数据结构的(没有细看是不是方法相似)
——————————分割线——————————
由数据范围可得我们的算法要在NlogN级
因为配对的舞伴要离开队列,很容易想到用链表,然而即便如此使用链表暴力仍然会T飞(我最初先用STL的list和数组模拟链表各做了一遍,都是只过了前8case,后面T飞)
思考原因
问题在于大多数候选答案不会因为离开队列而改变,再加上本题要求求所有候选答案中的最小值,考虑用优先队列维护
显然使用优先队列维护我们只需要O(N)在最开始跑一遍,后续O(NlogN)查找与更新
问题在于其实部分候选答案会改变,部分会被删除,也会因离队而新产生一些候选答案,这个很好想,脑子模拟一下会想到最多影响四个人只见的关系,对答案更新不大
因此对于有修改的优先队列,我们考虑两种处理方法
一,放弃,使用BST,这样BST支持查询与修改,然而我是懒鬼
二,双开优先队列,虽然复杂度仍是nlogn级,但常数略大
最后因为我们要维护答案的偏移量,我们需要知道舞者们彼此的站位关系,所以需要链表的辅助。
综上所述,本题我采用双向链表+两个优先队列维护
——————————分割线——————————
#include<bits/stdc++.h>
using namespace std;
#define re register
#define fo1(l,r) for(re int i=l;i<=r;++i)
#define fo2(l,r) for(re int j=l;j<=r;++j)
#define fo3(l,r) for(re int k=l;k<=r;++k)
#define fo4(l,r) for(re int tt=l;tt<=r;++tt)
#define inf 0x3f3f3f3f
#define INF 0x7fffffffffffffff
#define LL long long
#define itn int
inline int read()
{
int x=0,f=1;char ch=getchar();
while(!isdigit(ch))
{
if(ch=='-')
f=-1;
ch=getchar();
}
while(isdigit(ch))
{
x=(x<<3)+(x<<1)+ch-48;
ch=getchar();
}
return x*f;
}
const int N=2e5+10;
struct node
{
int l,r;
#define l(x) lss1[x].l
#define r(x) lss1[x].r
}lss1[N];
priority_queue<pair<int,int>,vector<pair<int,int> >,greater<pair<int,int> > > ans;
priority_queue<pair<int,int>,vector<pair<int,int> >,greater<pair<int,int> > > er;
int sum;
string s;int n,a[N],Ans[N][2],k;
int main()
{
n=read();cin>>s;s="0"+s;sum=n;
fo1(1,n)
{
a[i]=read();
if(i==1)
l(i)=n;
else
l(i)=i-1;
if(i==n)
r(i)=1;
else
r(i)=i+1;
}
fo1(1,n-1)
if(s[i]!=s[i+1])
ans.push(make_pair(abs(a[i]-a[i+1]),i));
while(!ans.empty())
{
itn bh1=ans.top().second,bh2=r(bh1);
if(!er.empty() && ans.top().first==er.top().first && bh1==er.top().second)
{
er.pop();ans.pop();
continue;
}
Ans[++k][0]=bh1;
Ans[k][1]=bh2;
ans.pop();
if(s[bh1]!=s[l(bh1)] && bh1>l(bh1))
er.push(make_pair(abs(a[bh1]-a[l(bh1)]),l(bh1)));
if(s[bh2]!=s[r(bh2)] && bh2<r(bh2))
er.push(make_pair(abs(a[bh2]-a[r(bh2)]),bh2));
if(s[l(bh1)]!=s[r(bh2)] && l(bh1)<r(bh2))
ans.push(make_pair(abs(a[l(bh1)]-a[r(bh2)]),l(bh1)));
r(l(bh1))=r(bh2);
l(r(bh2))=l(bh1);
}
printf("%d\n",k);
fo1(1,k)
printf("%d %d\n",Ans[i][0],Ans[i][1]);
return 0;
}

浙公网安备 33010602011771号