题目
给定一个𝑛个点的无向图以及参数数组𝑎1,𝑎2,...,𝑎𝑛与𝑏1,𝑏2,...,𝑏𝑛。𝑖与𝑗 (𝑖<𝑗)有边当且仅当𝑎𝑖−𝑎𝑗≤𝑖−𝑗≤𝑏𝑖−𝑏𝑗或𝑎𝑗−𝑎𝑖≤𝑗−𝑖≤𝑏𝑗−𝑏𝑖。 询问本图有多少个连通块。 数据范围:𝑛≤106,10−9≤𝑎𝑖,𝑏𝑖≤109。
做法
把i放到一边,j放到一边,得到两个不等式。按数组a的不等式从小到大排序,然后利用单调栈求连通块的个数。
#include<bits/stdc++.h>
using namespace std;
int n;
struct ty{long long a,b;
};
vector<ty> v;
bool cmp(ty a,ty b){if(a.a==b.a) return a.b<b.b;//b必须也从小到大,会影响栈顶的判断return a.a<b.a;
}
stack<long long> s;
int main(){scanf("%d",&n);for(int i=1;i<=n;i++){long long a,b;scanf("%lld%lld",&a,&b);v.push_back({a-i,i-b});}sort(v.begin(),v.end(),cmp);s.push(v[0].b);for(int i=1;i<n;i++){if(!s.empty()){if(v[i].b>=s.top()){long long minn=s.top();while(!s.empty()&&v[i].b>=s.top()){s.pop();}s.push(minn);}else if(v[i].b<s.top()){s.push(v[i].b);}}}cout<<s.size();
}