写了个奇怪的东西,我的思路是存离当前位置最近的后面的矛盾的值,然后找到不合法的位置再统计,然后last是记录会计算重复的位置。希望能有大佬证伪或者指出代码的问题,不胜感激之至!
码风不是很好,请多见谅
#include <bits/stdc++.h>
using namespace std;
long long n,p[300050],a,b,pos[300050],near[300050],last,m;
struct node{
long long v,pos;
bool operator < (const struct node &aa)const{return v>aa.v;}
};
priority_queue <node> q;
long long ans;
int main()
{
ios::sync_with_stdio(0);
cin.tie(0);cout.tie(0);
memset(near,0x3f,sizeof(near));
cin>>n>>m;
for(int i=1;i<=n;i++)
{
cin>>p[i];
pos[p[i]]=i;
}
for(int i=1;i<=m;i++)
{
cin>>a>>b;
if(pos[a]>pos[b])swap(a,b);
near[a]=min(near[a],pos[b]);
}
long long l=1,r=0;
while(r<=n)
{
r++;
while(!q.empty()&&q.top().pos<l)q.pop();
if(!q.empty()&&r==q.top().v)
{
long long k=r-1;
ans+=(k-l+1)*(k-l+2)/2;
if(last>=l)ans-=(last-l+1)*(last-l+2)/2;
while(near[p[l]]!=q.top().v)l++;
l++;
last=k;
q.pop();
}
q.push((node){near[p[r]],r});
}
r--;
ans+=(r-l+1)*(r-l+2)/2;
if(last>=l)ans-=(last-l+1)*(last-l+2)/2;
cout<<ans<<endl;
return 0;
}