zoukankan      html  css  js  c++  java
  • CF487E Tourists

    传送门

    很显然可以用圆方树转成一棵树,然后就可以愉快的上树剖了
    接下来考虑方点,当路径经过方点的时候,这个方点的贡献应该是它所表示的点双内的所有点的最小值
    然后我们可以考虑将每个方点用一个multiset存下当前点双内的所有点权
    但是发现修改时需要枚举包含当前圆点相邻的所有方点,当该图是菊花图时,就会被卡成(O(n^2))
    然后只好去看题解,居然发现志同道合的大佬,然后就借鉴了一下他的处理方法
    就是我们可以对于每个方点的multiset只存下它的子节点的权值
    那么每次修改就只需要修改当前圆点的父节点就好了
    但是这样做的弊端就是:当查询的两个点的lca是一个方点的时候,lca父节点的权值也要考虑进来(显然,lca代表的点双包括它的父节点)
    代码:

    #include<cstdio>
    #include<iostream>
    #include<set>
    #include<algorithm>
    using namespace std;
    void read(int &x) {
    	char ch; bool ok;
    	for(ok=0,ch=getchar(); !isdigit(ch); ch=getchar()) if(ch=='-') ok=1;
    	for(x=0; isdigit(ch); x=x*10+ch-'0',ch=getchar()); if(ok) x=-x;
    }
    #define rg register
    const int maxn=2e5+10;char p[3];
    int dep[maxn],f[maxn],top[maxn],n,m,k,w[maxn],tot,size[maxn];
    int dfn[maxn],low[maxn],tmp,st[maxn],tp,id[maxn],num,nid[maxn];
    multiset<int>d[maxn];
    struct segment_tree{int l,r,mn;}s[maxn*4];
    multiset<int>::iterator it;
    struct oo
    {
    	int cnt,pre[maxn*2],nxt[maxn*2],h[maxn];
    	void add(int x,int y)
    	{
    		pre[++cnt]=y,nxt[cnt]=h[x],h[x]=cnt;
    		pre[++cnt]=x,nxt[cnt]=h[y],h[y]=cnt;
    	}
    }a,b;
    void tarjan(int x,int fa)
    {
    	dfn[x]=low[x]=++tmp;st[++tp]=x;
    	for(rg int i=a.h[x];i;i=a.nxt[i])
    		if(a.pre[i]!=fa)
    		{
    			if(!dfn[a.pre[i]])
    			{
    				tarjan(a.pre[i],x);
    				low[x]=min(low[x],low[a.pre[i]]);
    				if(dfn[x]<=low[a.pre[i]])
    				{
    					tot++;int z;
    					do{z=st[tp--],b.add(z,tot);}while(z!=a.pre[i]);
    					b.add(x,tot);
    				}
    			}
    			else low[x]=min(low[x],dfn[a.pre[i]]);
    		}
    }
    void dfs(int x,int fa)
    {
    	size[x]=1;
    	for(rg int i=b.h[x];i;i=b.nxt[i])
    		if(b.pre[i]!=fa)
    		{
    			f[b.pre[i]]=x,dep[b.pre[i]]=dep[x]+1;
    			if(x>n)d[x].insert(w[b.pre[i]]);
    			dfs(b.pre[i],x),size[x]+=size[b.pre[i]];
    		}
    }
    void dfs2(int x,int f)
    {
    	top[x]=f,id[x]=++num;nid[num]=x;int k=0;
    	for(rg int i=b.h[x];i;i=b.nxt[i])
    		if(dep[b.pre[i]]>dep[x]&&size[b.pre[i]]>size[k])k=b.pre[i];
    	if(!k)return ;dfs2(k,f);
    	for(rg int i=b.h[x];i;i=b.nxt[i])
    		if(dep[b.pre[i]]>dep[x]&&k!=b.pre[i])dfs2(b.pre[i],b.pre[i]);
    }
    void update(int x){s[x].mn=min(s[x<<1].mn,s[x<<1|1].mn);}
    void build(int x,int l,int r)
    {
    	s[x].l=l,s[x].r=r;int mid=(l+r)>>1;
    	if(l==r){s[x].mn=nid[l]<=n?w[nid[l]]:*d[nid[l]].begin();return ;}
    	build(x<<1,l,mid),build(x<<1|1,mid+1,r);
    	update(x);
    }
    void change(int x,int a,int b,bool c)
    {
    	if(s[x].l==s[x].r)
    	{
    		if(c)s[x].mn=*d[nid[a]].begin();
    		else s[x].mn=b;
    		return ;
    	}
    	int mid=(s[x].l+s[x].r)>>1;
    	if(a<=mid)change(x<<1,a,b,c);
    	else change(x<<1|1,a,b,c);
    	update(x);
    }
    int get(int x,int a,int b)
    {
    	if(a<=s[x].l&&b>=s[x].r)return s[x].mn;
    	int mid=(s[x].l+s[x].r)>>1,ans=1e9;
    	if(a<=mid)ans=min(ans,get(x<<1,a,b));
    	if(b>mid)ans=min(ans,get(x<<1|1,a,b));
    	return ans;
    }
    int qsum(int x,int y)
    {
    	int ans=1e9;
    	while(top[x]!=top[y])
    	{
    		if(dep[top[x]]<dep[top[y]])swap(x,y);
    		ans=min(ans,get(1,id[top[x]],id[x]));
    		x=f[top[x]];
    	}
    	if(id[x]>id[y])swap(x,y);
    //	printf("%d %d
    ",x,y);
    	ans=min(ans,get(1,id[x],id[y]));
    	if(x>n)ans=min(w[f[x]],ans);
    	return ans;
    }
    int main()
    {
    	read(n),read(m),read(k),tot=n;
    	for(rg int i=1;i<=n;i++)read(w[i]);
    	for(rg int i=1,x,y;i<=m;i++)read(x),read(y),a.add(x,y);
    	tarjan(1,0),dfs(1,0),dfs2(1,1),build(1,1,num);
    	for(rg int i=1,x,y;i<=k;i++)
    	{
    		scanf("%s",p+1),read(x),read(y);
    		if(p[1]=='C')
    		{
    			if(f[x])d[f[x]].erase(w[x]),d[f[x]].insert(y),change(1,id[f[x]],y,1);
    			w[x]=y,change(1,id[x],y,0);
    		}
    		else printf("%d
    ",qsum(x,y));
    	}
    }
    
  • 相关阅读:
    HDU6470 ()矩阵快速幂
    O(1)乘法与快速乘O(log)
    imos 学习笔记五 抓拍 c#
    imos 学习笔记四 录像 c#
    imos 学习笔记三 下载指定时间段视频信息 c#
    imos学习笔记二 用户登录c#
    imos学习笔记一 sdk开发环境
    Hbase(nosql)体系结构有基本操作 笔记八
    zookeeper的安装与配置 笔记七
    mapReduce体系结构和各种算法 笔记六
  • 原文地址:https://www.cnblogs.com/lcxer/p/10617117.html
Copyright © 2011-2022 走看看