数据结构好题#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;
}

  

posted @ 2023-06-06 21:29  小鱼儿吼吼  阅读(14)  评论(0)    收藏  举报