Problem - B - Codeforces
题意就是给你m个数对,这两个人不是好朋友,其他的所有人都是好朋友,问1~n里面有多少个区间里面所有数都是好朋友
分析:
这题我分析的没错,但是在计算区间的时候,想的复杂了,用模拟去实现,其实不用,再做个最小值就好,当时没想到这么写。其实在模拟的时候都知道从后往前枚举,就不知道去从后往前处理一下后缀...
因为想要的区间里面都是好朋友,所以对于每一个i来说,都有一个截断的地方(如果没有就是n+1),比如举个例子 1 2 3 4 5
14 45
那对于1来说,从4就开始断了,所以区间的贡献就是4-1(1,12,123),这个区间计算很重要,我一开始从另外的角度去计算,过程就很麻烦。但是如果你以一个i为起点,然后去计算所能达到的最大值,这样也能计算完。
还有一种情况,就是i和j中全都是好朋友,但是区间里面有不是好朋友的
比如1 2 3 4 5,2 4的话,那1也只能到4,所以是大于i的最小值也需要考虑到,那就需要去计算一下最小的后缀。
综上所述,有两种情况需要处理,然后最后依次计算每个i所尽可能到边界所形成的区间的贡献
两种情况分别是:
第一种:对于每个i,找到最小的边界
第二种:对于比i大的数,找到最小的后缀
下面看代码就好:
#pragma GCC optimize(1)
#pragma GCC optimize(2)
#pragma GCC optimize(3,"Ofast","inline")
#define IOS ios::sync_with_stdio(false), cin.tie(0);
#include<iostream>
#include<map>
#include<set>
#include<cstdio>
#include<cstring>
#include<vector>
#include<stack>
#include<algorithm>
#include<cmath>
#include<queue>
#include<deque>
using namespace std;
#define int long long
typedef long long ll;
typedef pair<int,int> PAII;
const int N=2e6+10,M=5050,INF=1e18,mod=998244353;
map<int,int> mp;
signed main(){
//IOS;
int T;
//T=1;
cin>>T;
while(T--)
{
mp.clear();
int n,m;
cin>>n>>m;
for(int i=1;i<=n;i++) mp[i]=n+1;
for(int i=1;i<=m;i++)
{
int x,y;
cin>>x>>y;
if(x>y) swap(x,y);
mp[x]=min(mp[x],y);
}
for(int i=n-1;i>=1;i--)
if(mp[i]>mp[i+1]) mp[i]=mp[i+1];
int sum=0;
for(int i=1;i<=n;i++) sum+=mp[i]-i;
cout<<sum<<"\n";
}
return 0;
}
/*
*/