CF1175E Minimal Segment Cover(倍增)
阿新 • • 發佈:2020-11-16
類似的貪心思路,肯定找是通過這個點能到的最遠的點,這樣是最優的。
但是詢問次數很多,因此考慮用倍增思想,直接求出每個點通過2^i個邊能到的最遠點。
這是因為最後的答案一定是最小通過x條邊,並且這個x一定能被二進位制表示出來
#include<bits/stdc++.h> using namespace std; typedef long long ll; const int N=6e5+10; const int mod=1e9+7; const int inf=0x3f3f3f3f; int f[N][30]; int a[N]; int main(){ ios::sync_with_stdio(View Codefalse); int n,m; cin>>n>>m; int i; int sign=0; for(i=1;i<=n;i++){ int l,r; cin>>l>>r; a[l]=max(a[l],r); sign=max(sign,r); } for(i=1;i<=sign;i++){ a[i]=max(a[i-1],a[i]); } for(i=0;i<=sign;i++) f[i][0]=a[i]; for(i=1;i<=25;i++){ for(int j=0;j<=sign;j++){ f[j][i]=f[f[j][i-1]][i-1]; } } while(m--){ int l,r; int ans=0; cin>>l>>r; int tmp=l; for(i=20;i>=0;i--){ if(f[tmp][i]<r){ ans+=(1<<i); tmp=f[tmp][i]; } } if(a[tmp]>=r){ cout<<ans+1<<endl; } else{ cout<<-1<<endl; } } }