题目

题目背景
你知道 “二刺猿色狗” 吗?没错,它就是 比特色狗(bitset dog\text{bitset dog}bitset dog),大名鼎鼎的 Egg Egg Dog\text{Egg Egg Dog}Egg Egg Dog!

题目描述
今天,Byte\rm ByteByte 色狗给你出了一道经典的 bitset\rm bitsetbitset 题目:传递闭包。给出有向无环图 GGG,求 xxx 能到达的所有点。但是它加上了两种操作:

  • 将 xxx 能到达的所有点的点权设置为 vvv 。
  • 将 xxx 能到达的所有点的点权与 vvv 取较小值。

然后多次查询某个点的点权。你还会做吗?拥有「随切之力」的 DDG\sf DDGDDG 可是不费吹灰之力呢!

数据范围与约定
点数 n⩽105n\leqslant 10^5n⩽105,边数 m⩽105m\leqslant 10^5m⩽105,操作数 q⩽105q\leqslant 10^5q⩽105 。任意时刻点权在 [0,109][0,10^9][0,109] 内。时限 2s\rm 2s2s 。

思路

做了这道题,我对 时间轴 一直抱有警惕;做了这道题,我明白 修改可合并时可用 cdq\tt cdqcdq 。看到此题,修改明显可合并,立刻思考 cdq\tt cdqcdq 。但是 DAG\rm DAGDAG 上没有 “虚图”,虚树做法完全不可行。

然后就再不会了。从此忘掉时间轴的存在。于是被 FireWingBird\sf FireWingBirdFireWingBird 翅膀上的火焰灼烧。

再爱一次时间轴吧!如果一次操作必须 O(n)\mathcal O(n)O(n),那就 分块。进行了 O(n)\mathcal O(\sqrt n)O(n​) 个操作后,用 O(n)\mathcal O(n)O(n) 的时间将这些操作一并更新;查询的时候,暴力查看 O(n)\mathcal O(\sqrt{n})O(n​) 个还没有 “一并更新” 的修改。这不就又行了吗?

暴力是容易的,预处理传递闭包。略显困难的可能是 O(n)\mathcal O(\sqrt n)O(n​) 次修改,O(n)\mathcal O(n)O(n) 解决。直接 pushDown\tt pushDownpushDown 似乎有不知道先后顺序的困难——既然这是个偏序关系,那就按照这个偏序关系排序呗——按照时间从后往前加入 “设置点权” 的标记。每个点只需要访问 111 次,总时间 O(n)\mathcal O(n)O(n) 。

“对点权取较小值” 则比较麻烦了,因为它是二维偏序:既受到时间轴上,下一次 “设置点权” 标记的制约;又在数轴上,要取最小值。当然,延续上面的『每个点只修改一次』的想法,我们仍可以按照值排序;用 bitset\tt bitsetbitset 求出其会影响到的点(预处理 bitset\tt bitsetbitset 用来满足 “设置点权” 标记的制约;与传递闭包的 bitset\tt bitsetbitset 取交集即可)。这样复杂度是 O(n+nlog⁡n+nnω)\mathcal O(n+\sqrt{n}\log n+{n\sqrt{n}\over\omega})O(n+n​logn+ωnn​​) 的,看着叫人头大——虽说它的渐进复杂度其实没问题。

不妨采用第二种处理方式:Ynoi\rm YnoiYnoi 教导过我们,分块更适合配合 n\sqrt nn​ 数据结构,而非 log⁡\loglog 型。有用的 “对点权取较小值” 标记构成一个区间。这些标记不用考虑 “设置点权” 标记,因为不影响查询结果。进行经典分块。即,不需要考虑整块内的 “设置点权” 标记,就直接 pushDown\tt pushDownpushDown 了;最后边角部分暴力查。这样或许会容易实现些。

但是,这个出题人很混球,非要开 n⩽105n\leqslant 10^5n⩽105,导致 n2ωn^2\over\omegaωn2​ 的空间复杂度不可接受。必须做若干次,每次只考虑某 BBB 个点的传递闭包。注意:因为每个询问的复杂度不变,预处理所有数组,则时间复杂度是 O(nn+n2ω+m⋅nB)\mathcal O(n\sqrt n+{n^2\over\omega}+m\cdot\frac{n}{B})O(nn​+ωn2​+m⋅Bn​) 即只是单纯多次访问了操作序列。不要把 nBn\over BBn​ 乘到别的东西上面去了!空间复杂度 O(nBω)\mathcal O({nB\over\omega})O(ωnB​),取 B=n20B=\frac{n}{20}B=20n​ 等都可以轻易压缩空间。

代码

有一组数据过不了。不知道为什么。有端 怀疑是数据问题。

#include <cstdio> // JZM yydJUNK!!!
#include <iostream> // XJX yyds!!!
#include <algorithm> // XYX yydLONELY!!!
#include <cstring> // (the STRONG long for LONELINESS)
#include <cctype> // ZXY yydSISTER!!!
#include <bitset>
using namespace std;
# define rep(i,a,b) for(int i=(a); i<=(b); ++i)
# define rep0(i,a,b) for(int i=(a); i!=(b); ++i)
# define drep(i,a,b) for(int i=(a); i>=(b); --i)
typedef long long llong;
const int BUFFER_LENGTH = 1<<22;
char in_buf[BUFFER_LENGTH];
inline char getChar(){static char *S = in_buf, *T = S;if(S == T) S = in_buf, T = S +fread(S,1,BUFFER_LENGTH,stdin);return *(S ++);
}
inline int readint(){int a = 0, c = getChar(), f = 1;for(; !isdigit(c); c=getChar())if(c == '-') f = -f;for(; isdigit(c); c=getChar())a = (a<<3)+(a<<1)+(c^48);return a*f;
}
inline void writeint(int x){if(x > 9) writeint(x/10);putchar(int(x%10)^48);
}
inline void getMin(int &x, const int &y){if(y < x) x = y;
}const int MAXN = 100325;
struct Edge{ int to, nxt; };
Edge e[MAXN<<1]; int head[MAXN], cntEdge;
void addEdge(int a, int b){e[cntEdge].to = b, e[cntEdge].nxt = head[a];head[a] = cntEdge ++;
}
# define _go(i,x) for(int i=head[x]; ~i; i=e[i].nxt)int topo[MAXN], dfn, indeg[MAXN];
void scan(int x){topo[++ dfn] = x, indeg[x] = -1;_go(i,x) if((--indeg[e[i].to]) == 0)scan(e[i].to); // recurse
}const int MAXM = 20000;
std::bitset<MAXM> gra[MAXN];
void build(const int &l, const int &r){int* const _end = topo+dfn;for(int* i=_end; i!=topo; --i){gra[*i].reset(); // clear_go(j,*i) gra[*i] |= gra[e[j].to];if(l <= *i && *i < r) gra[*i].set(*i-l);}
}bool vis[MAXN];
void setBelong(int bel[], int x, const int &v){if(vis[x]) return ;static int que[MAXN];int *fro = que, *bac = que+1;for(vis[*bac=x]=true; fro!=bac; ){++ fro, x = *fro, bel[x] = v;_go(i,x) if(!vis[e[i].to]){vis[e[i].to] = true;++ bac, *bac = e[i].to;}}
}
void getValue(int v[]){int* const _end = topo+dfn+1;int *i1 = topo+1, *i2 = i1+1;for(; i1!=_end&&i2!=_end; i1+=2,i2+=2){_go(j1,*i1) getMin(v[e[j1].to],v[*i1]);_go(j2,*i2) getMin(v[e[j2].to],v[*i2]);}if(i1 != _end) _go(j,*i1) // updategetMin(v[e[j].to],v[*i1]);
}const int SQRTN = 320, MAXCNT = MAXN/SQRTN;
int bel[MAXCNT][MAXN], val[MAXCNT][MAXN];
const int INF = 0x7fffffff;
int cmd[MAXN][3], xyx[MAXN];
int main(){int n = readint(), m = readint(), q = readint();memset(head+1,-1,n<<2);for(int a,b; m; --m){a = readint(), b = readint();addEdge(a,b), ++ indeg[b];}rep(i,1,n) if(!indeg[i]) scan(i);rep0(i,0,q){cmd[i][0] = readint(), cmd[i][1] = readint();if(cmd[i][0] != 3) cmd[i][2] = readint();}const int CNTBLK = (q-1)/SQRTN+1;for(int i=0,lb=0; i!=CNTBLK; ++i,lb+=SQRTN){std::fill(val[i]+1,val[i]+n+1,INF);rep0(j,lb,lb+SQRTN) if(*cmd[j] == 2)getMin(val[i][cmd[j][1]],cmd[j][2]);getValue(val[i]); // pre-compute}memset(bel[0]+1,-1,n<<2);for(int p=0,lb=0; p+1!=CNTBLK; ++p,lb+=SQRTN){memcpy(bel[p+1]+1,bel[p]+1,n<<2);memset(vis+1,false,n); // only need oncedrep(i,lb+SQRTN-1,lb) if(*cmd[i] == 1)setBelong(bel[p+1],cmd[i][1],i); // set}for(int l=1,r=1+MAXM; l<=n; l=r,r+=MAXM){build(l,r); // just build itfor(int p=0,lb=0; p!=CNTBLK; ++p,lb+=SQRTN)rep0(i,lb,lb+SQRTN) if(*cmd[i] == 3){ // queryif(cmd[i][1] < l || r <= cmd[i][1])continue; // not to solve nowint v = bel[p][cmd[i][1]]; // in whole blockrep0(j,lb,i) if(*cmd[j] == 1)if(gra[cmd[j][1]].test(cmd[i][1]-l))v = j; // nearest operationif(v == -1){ // no setVal appliedxyx[i] = 0; continue; // done}# define updt(j) if(*cmd[j] == 2)          \if(gra[cmd[j][1]].test(cmd[i][1]-l))   \getMin(ans,cmd[j][2]) // update ansint ans = cmd[v][2]; // setValif(v < lb){ // across blocksconst int blk = v/SQRTN+1, rb = blk*SQRTN;rep0(j,v,rb) updt(j); // brutelyrep0(j,blk,p) getMin(ans,val[j][cmd[i][1]]);rep0(j,lb,i) updt(j); // gap}else rep0(j,v,i) updt(j); // withinxyx[i] = ans; // save result}}rep0(i,0,q) if(*cmd[i] == 3)writeint(xyx[i]), putchar('\n');return 0;
}

[ACNOI2022]Bitset Dog相关推荐

  1. Python 迁移学习实用指南:1~5

    原文:Hands-On Transfer Learning with Python 协议:CC BY-NC-SA 4.0 译者:飞龙 本文来自[ApacheCN 深度学习 译文集],采用译后编辑(MT ...

  2. codeforces1453 E. Dog Snacks

    E. Dog Snacks Heltion大佬题解 fuf_ufu​表示节点uuu到最近叶子节点的距离. 首先不难发现,考虑一棵子树根节点为uuu,一定每次都把一整棵子树上的食物吃完,然后再去别的子树 ...

  3. 算法复习——bitset(bzoj3687简单题)

    题目: Description 小呆开始研究集合论了,他提出了关于一个数集四个问题: 1.子集的异或和的算术和. 2.子集的异或和的异或和. 3.子集的算术和的算术和. 4.子集的算术和的异或和.   ...

  4. bitset类型, 标准库类型

    C++ primer 17.2 bitset类型, 标准库类型 1 使得位运算更容易实现, 并且能够处理超过最长整型大小的位集合. bitset定义在bitset中 定义和初始化bitset 1 bi ...

  5. 2016多校赛2 A 数学推公式 E 极角排序,组合数(待补) L dp+bitset优化

    2016 Multi-University Training Contest 2 A - Acperience 题意:给出w[],求S((w[i]-aB[i])^2)的最小值(B[i]为1或-1). ...

  6. bitset HDU6515 Coding Problem

    Coding Problem [ HDU - 6515 ] 题目大意:给你一个字符串,每个字母的ASCII二级制颠倒过来组成一个01数组. 然后这个数组每六位组成一个数字的ASCII输出 一道模拟题, ...

  7. 【JZOJ5064】【GDOI2017第二轮模拟day2】友好城市 Kosarajo算法+bitset+ST表+分块

    题面 在Byteland 一共有n 座城市,编号依次为1 到n,这些城市之间通过m 条单向公路连接. 对于两座不同的城市a 和b,如果a 能通过这些单向道路直接或间接到达b,且b 也能如此到达a,那么 ...

  8. bitset优化+滚动优化dp ----- 2021牛客多校第8场 F Robot

    题目大意: 就是给你一个大小为n∗mn*mn∗m的矩阵,里面有障碍物,每次询问给你一个机器人,以及机器人的起始位置,问你这个机器人能否从起点到终点 机器人有3种类型 只能往右走 只能往下走 可以往右走 ...

  9. 点分治问题 ----------- 2017杭州CCPC E.Master of Subgraph[bitset+点分治]

    题目链接 题目大意: 就是给你一颗树,树上每个点都有自己的权值,问你这棵树是否存在一棵子树,子树的权值和是[1,m][1,m][1,m]里面的,对于[1,m][1,m][1,m]里面的数,如果出现过就 ...

最新文章

  1. 余承东:国内用华为P40 Pro+就能拍照测体温,还很精准
  2. 今天有了意外收获,原来还可以这样提交数据的
  3. python ioctl_ioctl()函数 Unix/Linux
  4. 列索引对SharePoint大列表性能的影响
  5. 阿里云专访Redisson作者Rui Gu:构建开源企业级Redis客户端之路
  6. java二维数组存储数据,从键盘上录入学生人数,考试科目数,以及每个学生每科分数,输出每个学生的最高分、最低分、总分、平均分
  7. 非期望产出的sbm模型_投入产出模型在评价中应用的局限性
  8. [WORK]局数据系统
  9. android activity焦点,android启动activity文本框不获得焦点
  10. iSPRINT:Google 最高能的创新加速课程,让你 5 天就能验证创业想法!
  11. wpf之MVVM绑定背景色
  12. 400,404,500报错页面总结
  13. paip.提升安全性----Des加密 java php python的实现总结
  14. Ubuntu安装gcc 以及g++
  15. EdrawMax使用方法
  16. 初学Power bi项目财务与人力/利润表/人员结构-刘刘的第一篇学习记录文章
  17. 京沪高铁上火车位置的实时监视模拟网站的开发
  18. 圈内著名ts_央视为电竞发声:AG和estar当选著名战队,梦泪,猫神被官方肯定
  19. QQ群文件更改默认下载路径方法
  20. 优化算法——OWL-QN

热门文章

  1. 线特征作为视觉描述:用于视觉定位的上下文感知线特征描述符
  2. 基于移动终端的汉语手语识别技术研究
  3. 全国省市二级json,带id
  4. 《网络游戏核心技术与实战》读书笔记
  5. 免费域名证书最新申请方式大全
  6. idea 提取作者信息
  7. 几何光学学习笔记(9)- 3.3 理想光学系统的物像关系
  8. Android图片加载框架最全解析(八),带你全面了解Glide 4的用法
  9. A Brief History of Just-In-Time 简读
  10. openssl1.0.1 完美 升级到 1.0.1g脚本