WD与地图

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


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


显然倒序处理变成加边

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

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

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

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

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

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

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


Code:

#include <cstdio>
#include <cctype>
#include <algorithm>
#include <map>
#define ll long long
const int N=4e5+10;
using std::min;
template <class T>
void read(T &x)
{
x=0;char c=getchar();
while(!isdigit(c)) c=getchar();
while(isdigit(c)) x=x*10+c-'0',c=getchar();
}
std::map <int,int> ma[N];
struct node
{
int u,v,tim,ad;
bool friend operator <(node a,node b){return a.tim<b.tim;}
}E[N],El[N],Er[N];
struct Query
{
int op,a,b;
}Q[N];
int head[N],to[N<<1],Next[N<<1],cnt;
void add(int u,int v)
{
to[++cnt]=v,Next[cnt]=head[u],head[u]=cnt;
}
int n,m,q,k,_m;
int root[N],ch[N*60][2],siz[N*60],ct;
ll sum[N*60],ss[N],yuy[N],ans[N];
#define ls ch[now][0]
#define rs ch[now][1]
void upt(int &now,int l,int r,int p,int d)
{
if(!now) now=++ct;
if(l==r)
{
siz[now]+=d;
sum[now]=1ll*siz[now]*yuy[l];
return;
}
int mid=l+r>>1;
if(p<=mid) upt(ls,l,mid,p,d);
else upt(rs,mid+1,r,p,d);
siz[now]=siz[ls]+siz[rs];
sum[now]=sum[ls]+sum[rs];
}
int Merge(int x,int y,int l,int r)
{
if(!x||!y) return x^y;
if(l==r)
{
sum[x]+=sum[y];
siz[x]+=siz[y];
return x;
}
int mid=l+r>>1;
ch[x][0]=Merge(ch[x][0],ch[y][0],l,mid);
ch[x][1]=Merge(ch[x][1],ch[y][1],mid+1,r);
siz[x]=siz[ch[x][0]]+siz[ch[x][1]];
sum[x]=sum[ch[x][0]]+sum[ch[x][1]];
return x;
}
ll query(int now,int l,int r,int p)
{
if(l==r) return 1ll*p*yuy[l];
int mid=l+r>>1;
if(siz[rs]>=p) return query(rs,mid+1,r,p);
else return query(ls,l,mid,p-siz[rs])+sum[rs];
}
int f[N],hei[N],eu[N],ev[N],Tim;
void del(int id)
{
f[ev[id]]=ev[id];
if(eu[id]) --hei[eu[id]];
}
int Find(int x){return f[x]==x?x:Find(f[x]);}
void Merge2(int u,int v)
{
u=Find(u),v=Find(v);
if(u==v) return;
if(hei[u]<hei[v]) std::swap(u,v);
f[v]=u;
root[u]=Merge(root[u],root[v],1,k);
if(hei[u]==hei[v]) ++hei[u];
}
void Merge(int u,int v)
{
u=Find(u),v=Find(v);
if(u==v) return;
if(hei[u]<hei[v]) std::swap(u,v);
++Tim;
eu[Tim]=0,ev[Tim]=v;
f[v]=u;
if(hei[u]==hei[v])
{
++hei[u];
eu[Tim]=u;
}
}
int dfn[N],low[N],s[N],tot,in[N],dfsclock;
void tarjan(int now)
{
dfn[now]=low[now]=++dfsclock;
s[++tot]=now;
in[now]=1;
for(int v,i=head[now];i;i=Next[i])
{
v=to[i];
if(!dfn[v])
{
tarjan(v);
low[now]=min(low[now],low[v]);
}
else if(in[v])
low[now]=min(low[now],dfn[v]);
}
if(dfn[now]==low[now])
{
int k=s[tot--],las;
in[k]=0;
while(k!=now)
{
las=k,k=s[tot--];
in[k]=0;
Merge(las,k);
}
}
}
int pot[N];
void solve(int s,int t,int l,int r)
{
if(s>t) return;
int mid=l+r>>1;
int tim=Tim;
for(int i=s;i<=t;i++)
if(E[i].ad<=mid)
{
int u=Find(E[i].u),v=Find(E[i].v);
pot[++pot[0]]=u,pot[++pot[0]]=v;
add(u,v);
}
std::sort(pot+1,pot+pot[0]+1);
pot[0]=std::unique(pot+1,pot+pot[0]+1)-pot-1;
for(int i=1;i<=pot[0];i++)
{
int now=pot[i];
if(!dfn[now])
tarjan(now);
}
int lp=0,rp=0;
for(int i=s;i<=t;i++)
{
int u=E[i].u,v=E[i].v;
if(Find(u)==Find(v)) E[i].tim=mid,El[++lp]=E[i];
else Er[++rp]=E[i];
}
for(int i=1;i<=lp;i++) E[s+i-1]=El[i];
for(int i=1;i<=rp;i++) E[s+lp+i-1]=Er[i]; for(int i=1;i<=pot[0];i++) head[pot[i]]=dfn[pot[i]]=low[pot[i]]=0;
pot[0]=cnt=dfsclock=0; if(l!=r) solve(s+lp,t,mid+1,r);
while(Tim>tim) del(Tim--);
if(l!=r) solve(s,s+lp-1,l,mid);
}
int main()
{
read(n),read(m),read(q);k=n;
for(int i=1;i<=n;i++) read(ss[i]),yuy[i]=ss[i];
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;
for(int i=1;i<=q;i++)
{
read(Q[i].op),read(Q[i].a),read(Q[i].b);
if(Q[i].op==1) E[ma[Q[i].a][Q[i].b]].ad=q+1-i;
if(Q[i].op==2) ss[Q[i].a]+=Q[i].b,yuy[++k]=ss[Q[i].a];
}
std::sort(yuy+1,yuy+1+k);
k=std::unique(yuy+1,yuy+1+k)-yuy-1;
std::reverse(Q+1,Q+1+q);
for(int i=1;i<=n;i++) f[i]=i,hei[i]=1;
solve(1,m,0,q);
std::sort(E+1,E+1+m);
for(int i=1;i<=n;i++)
{
int p=std::lower_bound(yuy+1,yuy+1+k,ss[i])-yuy;
upt(root[i],1,k,p,1);
}
for(int j=1,i=1;i<=q;i++)
{
while(j<=m&&E[j].tim<=i)
{
Merge2(E[j].u,E[j].v);
++j;
}
if(Q[i].op==2)
{
int u=Q[i].a,dec=Q[i].b,rtu=Find(u);
int p=std::lower_bound(yuy+1,yuy+1+k,ss[u])-yuy;
upt(root[rtu],1,k,p,-1);
ss[u]-=dec;
p=std::lower_bound(yuy+1,yuy+1+k,ss[u])-yuy;
upt(root[rtu],1,k,p,1);
}
if(Q[i].op==3)
{
int u=Find(Q[i].a),t=Q[i].b;
if(siz[root[u]]<t) ans[++ans[0]]=sum[root[u]];
else ans[++ans[0]]=query(root[u],1,k,t);
}
}
for(int i=ans[0];i;i--) printf("%lld\n",ans[i]);
return 0;
}

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. stream,file,filestream,memorystream简单的整理

    一.Stream 什么是stream?(https://www.cnblogs.com/JimmyZheng/archive/2012/03/17/2402814.html#no8) 定义:提供字节序 ...

  2. MySQL 笔记整理(19) --为什么我只查一行的语句,也执行这么慢?

    笔记记录自林晓斌(丁奇)老师的<MySQL实战45讲> (本篇内图片均来自丁奇老师的讲解,如有侵权,请联系我删除) 19) --为什么我只查一行的语句,也执行这么慢? 需要说明一下,如果M ...

  3. Java HashMap 使用了未经检查或不安全的操作

    今天在做接口测试的时候使用了Java中的Map(java 所知胜少,因项目需要提供示例),不扯犊子了,我们直接看一个代码文件名:Test.java: import java.util.ArrayLis ...

  4. Web前端2019面试总结

    基础知识点   1.水平垂直居中 子绝父相,子盒子设置绝对定位,设置top:50%;left:50%,margin-top:-50%;margin-left:-50%; 子绝父相,子盒子设置绝对定位, ...

  5. 如何让nextcloud支持avi文件在线播放

    默认的nextcloud是不支持avi文件播放的,google查了一圈,都说是没法支持. 然而我觉得都是html5写的,为啥偏偏不支持. 查了一些资料,发现还是官方的代码少写了东西,可能是没考虑那么全 ...

  6. 用Gogs在Windows上搭建Git服务

    1.下载并安装Git,如有需求,请重启服务器让Path中的环境变量生效. 2.下载并安装Gogs,请注意,在Windows中部署时,请下载MiniWinService(mws)版本. 3.在Maria ...

  7. Android探究之View的绘制流程

    Android中Activity是作为应用程序的载体存在,代表着一个完整的用户界面,提供了一个窗口来绘制各种视图,当Activity启动时,我们会通过setContentView方法来设置一个内容视图 ...

  8. MongoDB自学(4)

    超过存储上限或记录条数删除最早的记录:db.createCollection("集合名",{capped:true,size:1024,max:100})注解:指定集合名的最大记录 ...

  9. Docker-Docker-compose应用

    Docker-compose是用来定义和运行多容器应用的工具,它是独立于docker存在的,需要单独安装.实际应用场景中,我们的应用可能被打包运行在不同的容器里面,例如一个常规的web应用可能会涉及到 ...

  10. 利用ZYNQ SOC快速打开算法验证通路(6)——LWIP实现千兆TCP/IP网络传输

    一.前言 之前ZYNQ与PC之间的网络连接依赖于外接硬件协议栈芯片,虽然C驱动非常简单,但网络带宽受限.现采用LWIP+PS端MAC控制器+PHY芯片的通用架构.关于LWIP库,已经有很多现成的资料和 ...