WD与地图

哎,我好傻啊,看了题解还弄错了一遍,靠着lbw指点才董


题意:给一个带点权有向图,要求支持删边,查询一个scc前\(k\)大权值,修改点权,强制在线。


显然倒序处理变成加边

考虑求出每条边两点在一个scc里面的最小时间

这样可以按时间对每个scc维护一个线段树,跑权值线段树合并

可以对每个边二分答案,然后想到整体二分

假设现在二分的时间为\([l,r]\),划分到这个区间的边为\([s,t]\)

那么小于\(l\)的边形成的图一定已经是一个scc了,我们用并查集维护一个类似虚图的东西维护每个已经好了的scc

然后把时间在\([l,mid]\)的边加入scc虚图跑tarjan,最后划分一下边\([s,t]\)进入左边还是右边

注意到维护scc的并查集需要可撤回


Code:

  1. #include <cstdio>
  2. #include <cctype>
  3. #include <algorithm>
  4. #include <map>
  5. #define ll long long
  6. const int N=4e5+10;
  7. using std::min;
  8. template <class T>
  9. void read(T &x)
  10. {
  11. x=0;char c=getchar();
  12. while(!isdigit(c)) c=getchar();
  13. while(isdigit(c)) x=x*10+c-'0',c=getchar();
  14. }
  15. std::map <int,int> ma[N];
  16. struct node
  17. {
  18. int u,v,tim,ad;
  19. bool friend operator <(node a,node b){return a.tim<b.tim;}
  20. }E[N],El[N],Er[N];
  21. struct Query
  22. {
  23. int op,a,b;
  24. }Q[N];
  25. int head[N],to[N<<1],Next[N<<1],cnt;
  26. void add(int u,int v)
  27. {
  28. to[++cnt]=v,Next[cnt]=head[u],head[u]=cnt;
  29. }
  30. int n,m,q,k,_m;
  31. int root[N],ch[N*60][2],siz[N*60],ct;
  32. ll sum[N*60],ss[N],yuy[N],ans[N];
  33. #define ls ch[now][0]
  34. #define rs ch[now][1]
  35. void upt(int &now,int l,int r,int p,int d)
  36. {
  37. if(!now) now=++ct;
  38. if(l==r)
  39. {
  40. siz[now]+=d;
  41. sum[now]=1ll*siz[now]*yuy[l];
  42. return;
  43. }
  44. int mid=l+r>>1;
  45. if(p<=mid) upt(ls,l,mid,p,d);
  46. else upt(rs,mid+1,r,p,d);
  47. siz[now]=siz[ls]+siz[rs];
  48. sum[now]=sum[ls]+sum[rs];
  49. }
  50. int Merge(int x,int y,int l,int r)
  51. {
  52. if(!x||!y) return x^y;
  53. if(l==r)
  54. {
  55. sum[x]+=sum[y];
  56. siz[x]+=siz[y];
  57. return x;
  58. }
  59. int mid=l+r>>1;
  60. ch[x][0]=Merge(ch[x][0],ch[y][0],l,mid);
  61. ch[x][1]=Merge(ch[x][1],ch[y][1],mid+1,r);
  62. siz[x]=siz[ch[x][0]]+siz[ch[x][1]];
  63. sum[x]=sum[ch[x][0]]+sum[ch[x][1]];
  64. return x;
  65. }
  66. ll query(int now,int l,int r,int p)
  67. {
  68. if(l==r) return 1ll*p*yuy[l];
  69. int mid=l+r>>1;
  70. if(siz[rs]>=p) return query(rs,mid+1,r,p);
  71. else return query(ls,l,mid,p-siz[rs])+sum[rs];
  72. }
  73. int f[N],hei[N],eu[N],ev[N],Tim;
  74. void del(int id)
  75. {
  76. f[ev[id]]=ev[id];
  77. if(eu[id]) --hei[eu[id]];
  78. }
  79. int Find(int x){return f[x]==x?x:Find(f[x]);}
  80. void Merge2(int u,int v)
  81. {
  82. u=Find(u),v=Find(v);
  83. if(u==v) return;
  84. if(hei[u]<hei[v]) std::swap(u,v);
  85. f[v]=u;
  86. root[u]=Merge(root[u],root[v],1,k);
  87. if(hei[u]==hei[v]) ++hei[u];
  88. }
  89. void Merge(int u,int v)
  90. {
  91. u=Find(u),v=Find(v);
  92. if(u==v) return;
  93. if(hei[u]<hei[v]) std::swap(u,v);
  94. ++Tim;
  95. eu[Tim]=0,ev[Tim]=v;
  96. f[v]=u;
  97. if(hei[u]==hei[v])
  98. {
  99. ++hei[u];
  100. eu[Tim]=u;
  101. }
  102. }
  103. int dfn[N],low[N],s[N],tot,in[N],dfsclock;
  104. void tarjan(int now)
  105. {
  106. dfn[now]=low[now]=++dfsclock;
  107. s[++tot]=now;
  108. in[now]=1;
  109. for(int v,i=head[now];i;i=Next[i])
  110. {
  111. v=to[i];
  112. if(!dfn[v])
  113. {
  114. tarjan(v);
  115. low[now]=min(low[now],low[v]);
  116. }
  117. else if(in[v])
  118. low[now]=min(low[now],dfn[v]);
  119. }
  120. if(dfn[now]==low[now])
  121. {
  122. int k=s[tot--],las;
  123. in[k]=0;
  124. while(k!=now)
  125. {
  126. las=k,k=s[tot--];
  127. in[k]=0;
  128. Merge(las,k);
  129. }
  130. }
  131. }
  132. int pot[N];
  133. void solve(int s,int t,int l,int r)
  134. {
  135. if(s>t) return;
  136. int mid=l+r>>1;
  137. int tim=Tim;
  138. for(int i=s;i<=t;i++)
  139. if(E[i].ad<=mid)
  140. {
  141. int u=Find(E[i].u),v=Find(E[i].v);
  142. pot[++pot[0]]=u,pot[++pot[0]]=v;
  143. add(u,v);
  144. }
  145. std::sort(pot+1,pot+pot[0]+1);
  146. pot[0]=std::unique(pot+1,pot+pot[0]+1)-pot-1;
  147. for(int i=1;i<=pot[0];i++)
  148. {
  149. int now=pot[i];
  150. if(!dfn[now])
  151. tarjan(now);
  152. }
  153. int lp=0,rp=0;
  154. for(int i=s;i<=t;i++)
  155. {
  156. int u=E[i].u,v=E[i].v;
  157. if(Find(u)==Find(v)) E[i].tim=mid,El[++lp]=E[i];
  158. else Er[++rp]=E[i];
  159. }
  160. for(int i=1;i<=lp;i++) E[s+i-1]=El[i];
  161. for(int i=1;i<=rp;i++) E[s+lp+i-1]=Er[i];
  162. for(int i=1;i<=pot[0];i++) head[pot[i]]=dfn[pot[i]]=low[pot[i]]=0;
  163. pot[0]=cnt=dfsclock=0;
  164. if(l!=r) solve(s+lp,t,mid+1,r);
  165. while(Tim>tim) del(Tim--);
  166. if(l!=r) solve(s,s+lp-1,l,mid);
  167. }
  168. int main()
  169. {
  170. read(n),read(m),read(q);k=n;
  171. for(int i=1;i<=n;i++) read(ss[i]),yuy[i]=ss[i];
  172. for(int i=1;i<=m;i++) read(E[i].u),read(E[i].v),E[i].tim=q+1,ma[E[i].u][E[i].v]=i;
  173. for(int i=1;i<=q;i++)
  174. {
  175. read(Q[i].op),read(Q[i].a),read(Q[i].b);
  176. if(Q[i].op==1) E[ma[Q[i].a][Q[i].b]].ad=q+1-i;
  177. if(Q[i].op==2) ss[Q[i].a]+=Q[i].b,yuy[++k]=ss[Q[i].a];
  178. }
  179. std::sort(yuy+1,yuy+1+k);
  180. k=std::unique(yuy+1,yuy+1+k)-yuy-1;
  181. std::reverse(Q+1,Q+1+q);
  182. for(int i=1;i<=n;i++) f[i]=i,hei[i]=1;
  183. solve(1,m,0,q);
  184. std::sort(E+1,E+1+m);
  185. for(int i=1;i<=n;i++)
  186. {
  187. int p=std::lower_bound(yuy+1,yuy+1+k,ss[i])-yuy;
  188. upt(root[i],1,k,p,1);
  189. }
  190. for(int j=1,i=1;i<=q;i++)
  191. {
  192. while(j<=m&&E[j].tim<=i)
  193. {
  194. Merge2(E[j].u,E[j].v);
  195. ++j;
  196. }
  197. if(Q[i].op==2)
  198. {
  199. int u=Q[i].a,dec=Q[i].b,rtu=Find(u);
  200. int p=std::lower_bound(yuy+1,yuy+1+k,ss[u])-yuy;
  201. upt(root[rtu],1,k,p,-1);
  202. ss[u]-=dec;
  203. p=std::lower_bound(yuy+1,yuy+1+k,ss[u])-yuy;
  204. upt(root[rtu],1,k,p,1);
  205. }
  206. if(Q[i].op==3)
  207. {
  208. int u=Find(Q[i].a),t=Q[i].b;
  209. if(siz[root[u]]<t) ans[++ans[0]]=sum[root[u]];
  210. else ans[++ans[0]]=query(root[u],1,k,t);
  211. }
  212. }
  213. for(int i=ans[0];i;i--) printf("%lld\n",ans[i]);
  214. return 0;
  215. }

2019.4.15

WD与地图 解题报告的更多相关文章

  1. 洛谷 P5162 WD与积木 解题报告

    P5162 WD与积木 题目背景 WD整日沉浸在积木中,无法自拔-- 题目描述 WD想买\(n\)块积木,商场中每块积木的高度都是\(1\),俯视图为正方形(边长不一定相同).由于一些特殊原因,商家会 ...

  2. [JSOI2008] [BZOJ1567] Blue Mary的战役地图 解题报告 (hash)

    题目链接:https://www.lydsy.com/JudgeOnline/problem.php?id=1567 Description Blue Mary最近迷上了玩Starcraft(星际争霸 ...

  3. CH Round #56 - 国庆节欢乐赛解题报告

    最近CH上的比赛很多,在此会全部写出解题报告,与大家交流一下解题方法与技巧. T1 魔幻森林 描述 Cortana来到了一片魔幻森林,这片森林可以被视作一个N*M的矩阵,矩阵中的每个位置上都长着一棵树 ...

  4. 洛谷_Cx的故事_解题报告_第四题70

    1.并查集求最小生成树 Code: #include <stdio.h> #include <stdlib.h>   struct node {     long x,y,c; ...

  5. Leetcode 115 Distinct Subsequences 解题报告

    Distinct Subsequences Total Accepted: 38466 Total Submissions: 143567My Submissions Question Solutio ...

  6. 【解题报告】洛谷 P2571 [SCOI2010]传送带

    [解题报告]洛谷 P2571 [SCOI2010]传送带今天无聊,很久没有做过题目了,但是又不想做什么太难的题目,所以就用洛谷随机跳题,跳到了一道题目,感觉好像不是太难. [CSDN链接](https ...

  7. 二模13day1解题报告

    二模13day1解题报告 T1.发射站(station) N个发射站,每个发射站有高度hi,发射信号强度vi,每个发射站的信号只会被左和右第一个比他高的收到.现在求收到信号最强的发射站. 我用了时间复 ...

  8. BZOJ 1051 最受欢迎的牛 解题报告

    题目直接摆在这里! 1051: [HAOI2006]受欢迎的牛 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 4438  Solved: 2353[S ...

  9. 习题:codevs 2822 爱在心中 解题报告

    这次的解题报告是有关tarjan算法的一道思维量比较大的题目(真的是原创文章,希望管理员不要再把文章移出首页). 这道题蒟蒻以前做过,但是今天由于要复习tarjan算法,于是就看到codevs分类强联 ...

随机推荐

  1. C# 构造tree菜单工具方法

    如何构造tree数据结构,做个笔记,方便查阅,本方法是直接返回json字符串: private string ToMenuJson(List<Model> data, string par ...

  2. Java笔记(day9~day10)

    继承: 好处:1.提高代码复用性:   2.让类之间产生关系,给多态提供了前提: 父类.子类 Java中支持单继承,不直接支持多继承,但对C++的多继承进行了改良 单继承:一个子类只能有一个直接复类 ...

  3. weUI之分页查询实现

    本文旨在介绍移动端h5分页查询实现 1.前端html 前端基于weui 样式库实现   参考http://jqweui.com/ <div class="weui-search-bar ...

  4. offsetLeft 解析

    前言:先看下w3c与之相关的介绍: element.offsetHeight 返回元素的高度. element.offsetWidth 返回元素的宽度. element.offsetLeft 返回元素 ...

  5. Jetty 开发指南: 嵌入式开发之HelloWorld

    Jetty 嵌入式之 HelloWorld 本节提供一个教程,演示如何快速开发针对Jetty API的嵌入式代码. 1. 下载 Jar 包 Jetty被分解为许多jar和依赖项,通过选择最小的jar集 ...

  6. 工具资源系列之给mac装个虚拟机

    mac 系统安装虚拟机目前有两种主流软件,一种是 Parallels Desktop ,另一种是 vmware. 本教程选用的是 vmware ,因为我之前 windows 上安装的虚拟机软件就是vm ...

  7. HTTP各个status code是什么意思【已解决】

    在介绍状态码之前,要简单讲一下为什么要有状态码这个东西.计算机之间的通信以协议为共同基础,客户端和服务端都按照协议的约定进行通信.HTTP的状态码就在HTTP的协议内,规定了很多的状态.客户端请求服务 ...

  8. CentOS 6忘记root密码的解决办法

    1.在开机启动的时候按键盘上的“E”键 或者“ESC”键,会进入如下界面 2.选择相应的内核,再次按“E”,出现下图,选择第二项,再次按“E”键 3.经过第二步,这个画面可以编辑,在信息的最后加“空格 ...

  9. Docker: Jenkins与Docker的自动化CI/CD流水线实战

    什么是CI/CD 持续集成(Continuous Integration,CI):代码合并.构建.部署.测试都在一起,不断地执行这个过程,并对结果反馈.持续部署(Continuous Deployme ...

  10. A Diversity-Promoting Objective Function for Neural Conversation Models论文阅读

    本文来自李纪为博士的论文 A Diversity-Promoting Objective Function for Neural Conversation Models 1,概述 对于seq2seq模 ...