「APIO 2019」桥梁
三天终于把\(APIO\)做完了
这题还是比较厉害的,如果不知道这是个分块应该就自闭了
考虑一个非常妙的操作,按照操作分块
我们设一个闸值\(S\),把\(S\)个边权修改操作分成一块,把所有的边分成两类,一类是在这个块内被修改过的边,一类是没有被修改过的边
我们把没有被修改过的边按照边权离线,同时把这个块内所有的询问离线,用并查集来维护这张图,只需要保证进行一次询问之前图中只有边权大于等于它的边
进行询问的时候当然还得考虑这个块内被修改过的边的贡献,对于这个块内被修改过但是修改的时间大于当前询问的,我们直接按照原来的权值把它加入并查集;对于修改时间小于询问时间的边,我们把其最后一次被修改的权值加入并查集
这个时候只需要查询一下询问所在联通块大小就好了
我们发现这里的这些操作还需要支持撤回,所以并查集就不能路径压缩了
但是卡卡常就过去了
代码
#include<bits/stdc++.h>
#define re register
#pragma GCC optimize(3)
#pragma GCC optimize("-fcse-skip-blocks")
#define getchar() (S==T&&(T=(S=BB)+fread(BB,1,1<<15,stdin),S==T)?EOF:*S++)
char BB[1<<18],*S=BB,*T=BB;
const int maxn=1e5+5;
inline int read() {
char c=getchar();int x=0;while(c<'0'||c>'9') c=getchar();
while(c>='0'&&c<='9') x=(x<<3)+(x<<1)+c-48,c=getchar();return x;
}
struct Edge{int u,v,rk,t,o,w;}e[maxn],r[maxn];
struct Ask{int o,x,y,rk;}q[maxn],g[maxn];
inline int cmp(const Edge &A,const Edge &B) {return A.o==B.o?A.w>B.w:A.o<B.o;}
inline int ctp(const Edge &A,const Edge &B) {return A.t<B.t;}
inline int cxp(const Ask &A,const Ask &B) {return A.y>B.y;}
inline int cop(const Edge &A,const Edge &B) {return A.rk<B.rk;}
int n,m,cnt,s,Q,now;
int fa[maxn],sz[maxn],st1[maxn],st2[maxn],f[maxn],top,Ans[maxn],st[maxn],pt,U[maxn],V[maxn];
inline int find(int x) {while(x!=fa[x]) x=fa[x];return x;}
inline void back(int x) {sz[st1[x]]-=sz[st2[x]];fa[st2[x]]=st2[x];}
inline void merge(int x,int y) {
int xx=find(x),yy=find(y);
if(xx==yy) return;
if(sz[xx]<sz[yy]) fa[xx]=yy,sz[yy]+=sz[xx],st1[++top]=yy,st2[top]=xx;
else fa[yy]=xx,sz[xx]+=sz[yy],st1[++top]=xx,st2[top]=yy;
}
inline void calc(int t) {
for(re int i=1;i<=now;i++) {
if(r[i].t>g[t].rk) break;
if(!f[r[i].rk]) st[++pt]=r[i].rk,U[pt]=r[i].u,V[pt]=r[i].v;
f[r[i].rk]=q[r[i].t].y;
}
for(re int i=now;i;--i) {
if(r[i].t<g[t].rk) break;
if(r[i].t>g[t].rk&&!f[r[i].rk]&&r[i].w>=g[t].y)
merge(r[i].u,r[i].v);
}
while(pt) {
if(f[st[pt]]>=g[t].y) merge(U[pt],V[pt]);
f[st[pt]]=0;--pt;
}
Ans[g[t].rk]=sz[find(g[t].x)];
while(top) back(top--);
}
inline void solve(int L,int R) {
if(L>R) return;
int H=0,tot=1;now=0;
for(re int i=1;i<=n;i++) fa[i]=i,sz[i]=1;
for(re int i=L;i<=R;i++)
if(q[i].o==1) e[q[i].x].t=i,e[q[i].x].o=1,r[++now]=e[q[i].x];
else g[++H]=q[i];
std::sort(r+1,r+now+1,ctp);
std::sort(g+1,g+H+1,cxp);std::sort(e+1,e+m+1,cmp);
for(re int i=1;i<=m;i++) {
if(e[i].o) break;
while(tot<=H&&e[i].w<g[tot].y) calc(tot),tot++;
int xx=find(e[i].u),yy=find(e[i].v);
if(xx!=yy) {
if(sz[xx]<=sz[yy]) sz[yy]+=sz[xx],fa[xx]=yy;
else sz[xx]+=sz[yy],fa[yy]=xx;
}
}
while(tot<=H) calc(tot),tot++;
std::sort(e+1,e+m+1,cop);
for(re int i=L;i<=R;i++) if(q[i].o==1) e[q[i].x].o=0,e[q[i].x].w=q[i].y;
}
int main() {
n=read(),m=read();
for(re int i=1;i<=m;i++)
e[i].u=read(),e[i].v=read(),e[i].w=read(),e[i].rk=i;
Q=read();s=3.4*std::sqrt(m);
int l=1;
for(re int i=1;i<=Q;i++) {
q[i].o=read(),q[i].x=read(),q[i].y=read();q[i].rk=i;
if(q[i].o==1) ++cnt;
if(cnt>=s) solve(l,i),cnt=0,l=i+1;
}
solve(l,Q);
for(re int i=1;i<=Q;i++) if(q[i].o==2) printf("%d\n",Ans[i]);
return 0;
}
「APIO 2019」桥梁的更多相关文章
- #3145. 「APIO 2019」桥梁
#3145. 「APIO 2019」桥梁 题目描述 圣彼得堡市内所有水路长度总和约 282 千米,市内水域面积占城市面积的 7%.--来自维基百科 圣彼得堡位于由 \(m\) 座桥梁连接而成的 \(n ...
- #3146. 「APIO 2019」路灯
#3146. 「APIO 2019」路灯 题目描述 一辆自动驾驶的出租车正在 Innopolis 的街道上行驶.该街道上有 \(n + 1\) 个停车站点,它们将街道划分成了 \(n\) 条路段.每一 ...
- #3144. 「APIO 2019」奇怪装置
#3144. 「APIO 2019」奇怪装置 题目描述 考古学家发现古代文明留下了一种奇怪的装置.该装置包含两个屏幕,分别显示两个整数 \(x\) 和 \(y\). 经过研究,科学家对该装置得出了一个 ...
- 【LOJ #3144】「APIO 2019」奇怪装置
题意: 定义将一个\(t\)如下转换成一个二元组: \[ f(t) = \begin{cases} x = (t + \left\lfloor \frac{t}{B} \right \rfloor) ...
- 「APIO 2019」路灯
题目 显然一个熟练的选手应该能一眼看出我们需要维护点对的答案 显然在断开或连上某一条边的时候只会对左右两边联通的点产生贡献,这个拿\(set\)维护一下就好了 那现在的问题就是怎么维护了 考虑一个非常 ...
- 「APIO 2019」奇怪装置
题目 考虑推柿子 最开始的想法是如果两个\(t\)在\(mod\ B\)意义下相等,那么只需要比较一下\((t+\left \lfloor \frac{t}{B}\rfloor \right)mod\ ...
- 「WC 2019」数树
「WC 2019」数树 一道涨姿势的EGF好题,官方题解我并没有完全看懂,尝试用指数型生成函数和组合意义的角度推了一波.考场上只得了 44 分也暴露了我在数数的一些基本套路上的不足,后面的 \(\ex ...
- LOJ#3054. 「HNOI 2019」鱼
LOJ#3054. 「HNOI 2019」鱼 https://loj.ac/problem/3054 题意 平面上有n个点,问能组成几个六个点的鱼.(n<=1000) 分析 鱼题,劲啊. 容易想 ...
- 【题解】#6622. 「THUPC 2019」找树 / findtree(Matrix Tree+FWT)
[题解]#6622. 「THUPC 2019」找树 / findtree(Matrix Tree+FWT) 之前做这道题不理解,有一点走火入魔了,甚至想要一本近世代数来看,然后通过人类智慧思考后发现, ...
随机推荐
- composer(作曲家)安装php-ml
刚开始我用的是up5.6版本php命令安装composer 后来使用composer时发现命令行会提示php版本太低 于是我下载了wamp,使用7.1版本的php重新安装了composer,因为php ...
- NX二次开发-设置WCS位置UF_CSYS_set_wcs
NX9+VS2012 UF_initialize(); //输入X向量Y向量输出一个3*3矩阵 ] = {0.0, 0.0, 1.0}; ] = {0.0, 1.0, 0.0}; ]; UF_MTX3 ...
- [JZOJ 5818] 做运动
题意:带温度最短路. 思路: 我们将温度从小到大的将边加入,用并查集维护连通性. 如果一旦联通那么跑一遍\(spfa\)就可以得到答案. 复杂度\(O(m log m)\) #include < ...
- Portainer Exec Container 失败解决方案
近日,将portainer服务挂了个域名,然后用Nginx代理的时候发现不能attach容器了,经过搜索在issue 找到解决方案 1.修改Nginx config server { listen 8 ...
- [转]ThinkPHP分页实例
很多人初学thinkphp时,不太熟悉thinkphp的分页使用方法,现在将自己整理的分页方法分享下,有需要的朋友可以看看. 控制器中的代码: $db = M("cost" ...
- Python3入门机器学习经典算法与应用✍✍✍
Python3入门机器学习经典算法与应用 整个课程都看完了,这个课程的分享可以往下看,下面有链接,之前做java开发也做了一些年头,也分享下自己看这个视频的感受,单论单个知识点课程本身没问题,大家看的 ...
- 【POJ】3278 Catch That Cow
题目链接:http://poj.org/problem?id=3278 题意:有一头奶牛跑到了K的位置,农夫在N的位置,求最短抓到奶牛的时间. 农夫有两种移动方式. 1.步行:一分钟内从x->x ...
- asp.net core2.0 依赖注入 AddTransient与AddScoped的区别 - 晓剑 - CSDN博客
原文:asp.net core2.0 依赖注入 AddTransient与AddScoped的区别 - 晓剑 - CSDN博客 原文地址:http://www.tnblog.net/aojiancc2 ...
- C9 vs 三星
我还是更喜欢 C9, 可惜当年的牛B人物 LemonNation 不在了,C9 赢 三星 一局的机会都没有了. 伟大的 LemonNation ,软件工程学硕士, 2014年,LemonNation ...
- spring MVC <mvc:annotation-driven>
研究SpringMvc 3.2的<mvc:annotation-driven>默认干了什么 如果不配置其他参数,大致相当于以下的配置文件(参考自org.springframework.we ...