题面



$ solution: $

真的没有想到可以用分块。

但是可以发现一个性质,每个询问只关心这个点最后一次赋值操作,和这个赋值操作后的所有取 $ min $ 操作。这个感觉很有用,但是真的很难让人想到低于 $ n\times m $ 的做法。基于 $ DAG $ 的数据结构是目前很少需要掌握的(好吧我都不知道有什么数据结构可以维护 $ DAG $ )所以肯定得骚操作。

我们可以发现一个 $ DAG $ 的性质,如果有一连串赋值操作我们可以根据拓扑序 $ O(n) $ 将所有操作完成,直接按顺序从后往前赋值,这样每个点赋值之后就不会再被访问。同理的, 如果有一连串取 $ min $ 操作我们也可以根据拓扑序 $ O(n) $ 将所有操作完成,直接 $ min $ 值从小到大取 $ min $, 这样每个点在取 $ min $ 之后就不会再被访问。但是当我们将这两种操作合到一起时就不行了。

但是联想一下上面说的性质:每个询问只关心这个点最后一次赋值操作,和这个赋值操作后的所有取 $ min $ 操作。我们可以搞出一个分块来,先预处理2操作,将2操作序列分块,并将每一块用上面的方法统计出每个结点在每个块内的取 $ min $ 后的值(初值inf)。然后我们就可以 $ \sqrt{n} $ 的求出任意一个区间里某个节点取 $ min $ 的最小值(其实还需要一个操作)。然后我们只需要快速找到每个询问的节点的最后一次赋值操作的编号,即赋值的大小,就可以得到答案。找到这个编号,我们可以对1操作分块来完成。

但是上述操作我们还需要知道一个东西,因为分块两边的小区间是要暴力遍历的,这个我们需要知道每个操作能否对某个点产生影响,这个等同于我们要知道 $ DAG $ 中一个点能否到另一个点。这个很奇妙的我们可以用 $ bitset $ 暴力完成。因为这个是无法用低于 $ n\times m $ 的复杂度完成,但是只涉及能否我们可以用二进制

  1. 仔细分析求得答案需要什么关键信息
  2. 对于一连串操作可以一次完成,就考虑分治或分块
  3. 对于两种操作会互相影响,考虑先预处理一种操作在进行第二种操作
  4. 二进制和是与否,这个对于复杂度优化很好用。
  5. $ DAG $ 中的一些问题是难以用低于 $ n\times m $ 的做法完成的!



$ code: $

#include<iostream>
#include<cstdio>
#include<iomanip>
#include<algorithm>
#include<cstring>
#include<cstdlib>
#include<ctime>
#include<cmath>
#include<vector>
#include<queue>
#include<map>
#include<set>
#include<bitset> #define ll long long
#define db double
#define rg register int using namespace std; int tt,t=1;
int n,m,q,ff;
int a[100005];
int idx[100005];
int fq[100005];
int fm[100005][404];
int vis[100005];
bitset<100005> f[100005]; struct su{
int to,next;
}b[200005];
int tou[100005]; struct pi{
int id,x,v,op;
inline bool operator <(const pi &i)const{
return v<i.v;
}
}s[100005],k[100005]; inline int qr(){
register char ch; register bool sign=0; rg res=0;
while(!isdigit(ch=getchar()))if(ch=='-')sign=1;
while(isdigit(ch))res=res*10+(ch^48),ch=getchar();
if(sign)return -res; else return res;
} inline void yu(int i){ //预处理dag中两点是否可达
vis[i]=1; f[i][i]=1;
for(rg j=tou[i];j;j=b[j].next){
if(!vis[b[j].to]) yu(b[j].to);
f[i]|=f[b[j].to];
}
} inline void dfs(int i,int v,int time,bool op){ //修改操作
if(vis[i]==t)return ; else vis[i]=t; //根据op判断是1操作还是2操作
if(op) a[i]=v,idx[i]=time; else fm[i][time]=v;
for(rg j=tou[i];j;j=b[j].next){
if(vis[b[j].to]==t)continue;
dfs(b[j].to,v,time,op);
}
} int main(){
//freopen("dag.in","r",stdin);
//freopen("dag.out","w",stdout);
n=qr(); m=qr(); q=qr(); ff=sqrt(q-1)+1;
for(rg i=1;i<=q;++i) fq[i]=(i-1)/ff+1; //分块
for(rg i=1;i<=m;++i){
rg x=qr(),y=qr();
b[i]=su{y,tou[x]}; tou[x]=i;
}
for(rg i=1;i<=n;++i) if(!vis[i])yu(i);
for(rg i=1;i<=q;++i){ //先预处理每个块内的2操作
rg op=qr(); s[i]=pi{i,qr(),0,op};
if(op<=2) s[i].v=qr();
if(op==2) k[++tt]=s[i];
if(fq[i]!=fq[i+1]){
sort(k+1,k+tt+1); ++t; //从小到大,保证每个点只修改一次
for(rg j=1;j<=n;++j) fm[j][fq[i]]=1e9; //赋初值
for(rg j=1;j<=tt;++j)
dfs(k[j].x,k[j].v,fq[i],0);
tt=0;
}
}
for(rg i=1;i<=q;++i){
if(s[i].op==3){
rg x=s[i].x,y=idx[x],v=a[x],sf=0;
for(rg j=i;fq[j]==fq[i];--j){ //在同一个块内,暴力处理
if(s[j].op==1&&f[s[j].x][x]){ sf=1; y=j; v=s[j].v;
for(rg o=y;o<=i;++o)
if(s[o].op==2&&f[s[o].x][x]) v=min(v,s[o].v);
break;
}
}
if(!sf){ //这个if调了半个上午
for(rg j=y+1;fq[j]==fq[y];++j) //前小块
if(s[j].op==2&&f[s[j].x][x]) v=min(v,s[j].v);
for(rg j=fq[y]+1;j<=fq[i]-1;++j) v=min(v,fm[x][j]); //中间的大块
for(rg j=i;fq[j]==fq[i];--j) //后小块
if(s[j].op==2&&f[s[j].x][x]) v=min(v,s[j].v);
}
printf("%d\n",v);
}
if(fq[i]!=fq[i+1]){ ++t; //将这个块内的1操作一遍做完
for(rg j=i;fq[j]==fq[i];--j)
if(s[j].op==1)dfs(s[j].x,s[j].v,j,1);
}
}
return 0;
}

最新文章

  1. 一文搞懂HMM(隐马尔可夫模型)
  2. 数百个 HTML5 例子学习 HT 图形组件 – 3D建模篇
  3. powerdesigner显示列描述信息
  4. c++双字符常量
  5. Package &#39;DXCore for Visual Studio&#39; has failed to load properly
  6. 判断不在Update Task中
  7. 关系数据库 范式(NF: Normal Form) 说明
  8. 计算机学院大学生程序设计竞赛(2015’12) 1006 01 Matrix
  9. 关于ionic开发的一些总结(项目启动设置,app图标名称更改)
  10. 设计模式总结(Java)—— 适配器模式
  11. python如何进行内存管理
  12. C#机器学习之判断日报是否合格
  13. asp.net 根据连接地址保存文件,图片
  14. Variational RL for POMDP
  15. lnmp部署知乎出现403
  16. Windows的空格预览神器 | QuickLook
  17. hdu多校1002 Balanced Sequence
  18. Android 插件化 开发
  19. Ilist&lt;object&gt;转换成I&lt;实体&gt; 如何转换
  20. Swift is Open Source 博客note

热门文章

  1. java内存分布详解
  2. 五、python中MD5加密
  3. 4.2.k8s.Ingress-Nginx
  4. 【Spring】---属性注入
  5. JavaWeb项目:Shiro实现简单的权限控制(整合SSM)
  6. 【ABAP系列】SAP ABAP系统变量及注释
  7. 在linux服务器上自动备份数据库
  8. anaconda3,将python版本回退(python3.7---python3.5)
  9. Java内存管理和回收
  10. Vim文本编辑工具