专栏文章
P14449 [ICPC 2025 Xi'an R] Catch the Monster
P14449题解参与者 1已保存评论 0
文章操作
快速查看文章及其快照的属性,并进行相关操作。
- 当前评论
- 0 条
- 当前快照
- 1 份
- 快照标识符
- @mina44h9
- 此快照首次捕获于
- 2025/12/01 23:03 3 个月前
- 此快照最后确认于
- 2025/12/01 23:03 3 个月前
此篇为 dmy 比赛复盘。
对于这种连续区间查询的题,容易想到双指针维护对于每个 ,能到达最远的不违反条件的 ,这样就能 查询了。
这道题推一推不难发现满足条件的树是一棵毛毛虫树,即对于每个点,不存在其有大于等于三个度数大于等于 的点。
我们考虑每次加入点怎么快速维护。枚举每条包含该点的边, 是不难维护的,唯一的问题是,当加入这条边后, 的度数增加,可能会导致与 相邻的一个点受到影响,直接枚举时间是无法承受的。但发现只有当 的那个点加入时,当 又连一条边时他不会收到更新,而其他的由于本来 ,就会计入答案。所以不妨维护 ,每次加边时 加上 等,虽然当 后这个 无意义,但由于我们只需要当 时多更新,此时这个值是确定值,维护完毕。删除点同理。
CPP#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";
}
}
相关推荐
评论
共 0 条评论,欢迎与作者交流。
正在加载评论...