P14449 [ICPC 2025 Xi'an R] Catch the Monster
此篇为 dmy 比赛复盘。
对于这种连续区间查询的题,容易想到双指针维护对于每个
这道题推一推不难发现满足条件的树是一棵毛毛虫树,即对于每个点,不存在其有大于等于三个度数大于等于
我们考虑每次加入点怎么快速维护。枚举每条包含该点的边,
#include <bits/stdc++.h>
using namespace std;
// #define int long long
#define pb push_back
#define eb emplace_back
#define all(x) (x).begin(),(x).end()
#define fi first
#define se second
#define SZ(x) ((int)(x).size())
typedef vector<int> VI;
typedef long long ll;
typedef pair<int,int> PII;
const ll MOD=998244353;
// head
const int N=1e6+5;
vector<vector<int>> G(N);
int ans[N];
int du[N],cnt[N],las[N],sum;
void upd(int x,int k)
{
sum-=(cnt[x]>=3);
cnt[x]+=k;
sum+=(cnt[x]>=3);
}
signed main()
{
cin.tie(nullptr);
ios::sync_with_stdio(false);
int n,m,q;cin>>n>>m>>q;
for(int i=1;i<=m;i++){
int u,v;cin>>u>>v;
G[u].pb(v);
G[v].pb(u);
}
for(int i=n,j=n;i>=1;i--){
for(auto it:G[i]){
if(it<i||it>j) continue;
du[it]++,du[i]++;
if(du[it]==2) upd(las[it],1);
if(du[i]==2) upd(las[i],1);
if(du[it]>=2) upd(i,1);
if(du[i]>=2) upd(it,1);
las[it]+=i,las[i]+=it;
}
while(sum)
{
for(auto it:G[j]){
if(it<i||it>j) continue;
if(du[j]>=2) upd(it,-1);
las[it]-=j;
du[it]--;
if(du[it]==1) upd(las[it],-1);
}
sum-=(cnt[j]>=3);
j--;
}
ans[i]=j;
}
while(q--)
{
int l,r;cin>>l>>r;
if(ans[l]>=r) cout<<"Yes\n";
else cout<<"No\n";
}
}