2 条题解
-
0
首先离线处理。
然后你就会发现这题的
A操作的作用仅限于告诉你R操作删除了哪条边,然后离线处理时加上即可。答案部分搜索一下就行了。
#include<bits/stdc++.h> using namespace std; const int N=2e5+10; int v[N],v1[N],f[N],op[N],ans[N]; struct node{int x,y;}e[N]; vector<int>G[N]; void dfs(int x,int vv) { ans[x]=max(ans[x],vv); for(int y:G[x])if(!ans[y])dfs(y,vv); } signed main() { int n,q;cin>>n>>q; vector<node>vec; for(int i=1;i<=q;i++) { string s;cin>>s; if(s[0]=='D') op[i]=1,cin>>e[i].x; if(s[0]=='A') op[i]=2,cin>>e[i].x>>e[i].y, vec.push_back({e[i].x,e[i].y}); if(s[0]=='R') op[i]=3,cin>>e[i].x; } for(int i=1;i<=n;i++)v[i]=1; for(int i=1;i<=vec.size();i++)v1[i]=1; for(int i=1;i<=q;i++) { if(op[i]==1)v[e[i].x]=0; if(op[i]==3)v1[e[i].x]=0; } for(int i=1;i<=vec.size();i++)if(v1[i]) G[vec[i-1].x].push_back(vec[i-1].y), G[vec[i-1].y].push_back(vec[i-1].x); for(int i=1;i<=n;i++)if(v[i])dfs(i,q); for(int i=q;i>=1;i--) { if(op[i]==1) { int x=e[i].x;if(ans[x])continue; dfs(x,i-1); } if(op[i]==3) { int x=vec[e[i].x-1].x,y=vec[e[i].x-1].y; G[x].push_back(y); G[y].push_back(x); if(ans[x]==0&&ans[y]==0)continue; dfs(x,i-1);dfs(y,i-1); } } for(int i=1;i<=n;i++)cout<<ans[i]<<'\n'; return 0; } -
0
鉴定为语文阅读题。
注意到操作
A x y一定是链接两个活跃农场这启示了我们几点。首先一个点肯定不会在停产之后进行
A操作。进一步地,一个点变得无关,只可能是经历了
D x操作且断掉了所有与活跃农场的边的路径,而且变得无关就不会建边,所以一个农场的有关的时间是一个形如 的东西。同时我们发现建边之前两个端点都是活跃的,所以这条边的建立时间不会对答案产生影响,但是删除是会的,我们可以记录它的删除时间 。
其实这里做法就可以分成两种了,一种是倒过来,删点变成加点,删边变成加边们可以用并查集。
我的做法复杂一点,我们发现题目中所有输出的最大值一定是最大的 ,而每个点的输出值也不会小于 ,我们将 初始化答案 。
接下来,我们用优先队列维护,每个点只取一次,每次取出一个最大值的点尝试更新相连的点。
只要我还有关,我们的边还在,你就还是有关的,所以我们更新点的方式也就是尝试 。
我们就这样一直更新就行了,时间复杂度是 ,没有并查集做法那么优秀。
但是好写好理解!
#include<bits/stdc++.h> #define LL long long #define val first #define num second using namespace std; const LL N=2e5+5; LL n,q,ans[N],x,y,cnt,e[N][2],r[N],vis[N],age[N]; char c[15]; vector<pair<LL,LL> >v[N]; priority_queue<pair<LL,LL> >p; int main() { scanf("%lld%lld",&n,&q); for(int i=1;i<=N;i++) { age[i]=-1,r[i]=-1; } for(int Q=1;Q<=q;Q++) { scanf("%s",c); if(c[0]=='D') { scanf("%lld",&x); if(age[x]==-1)age[x]=Q-1; } if(c[0]=='A') { scanf("%lld%lld",&x,&y); ++cnt; v[x].push_back({y,cnt}); v[y].push_back({x,cnt}); } if(c[0]=='R') { scanf("%lld",&x); r[x]=Q-1; } } for(int i=1;i<=cnt;i++) { if(r[i]==-1)r[i]=q; } for(int i=1;i<=n;i++) { if(age[i]==-1)age[i]=q; } for(int i=1;i<=n;i++) { ans[i]=age[i]; p.push({ans[i],i}); } while(!p.empty()) { LL t=p.top().num; p.pop(); if(vis[t])continue; vis[t]=1; for(pair<LL,LL> i:v[t]) { if(ans[i.val]<min(ans[t],r[i.num])) { ans[i.val]=min(ans[t],r[i.num]); p.push({ans[i.val],i.val}); } } } for(int i=1;i<=n;i++) { printf("%lld\n",ans[i]); } return 0; }
- 1
信息
- ID
- 7660
- 时间
- 1000ms
- 内存
- 128MiB
- 难度
- 8
- 标签
- 递交数
- 17
- 已通过
- 6
- 上传者