zoukankan      html  css  js  c++  java
  • CF487E Tourists

    题目链接
    还是圆方树.
    考虑如果可以走到一个连通分量,一定可以走到这个连通分量的最小值.
    那么维护搜索栈,找点双.
    这一部分自行学习.
    假设已经建出了圆方树,然后(dfs)一遍.
    圆点直接维护权值,方点用一个(multiset)维护它的所有儿子的权值.
    然后树剖+线段树维护区间最小值即可.
    注意询问的时候如果(LCA)是方点还要算上它父亲的贡献.
    哦这道题不是仙人掌.
    所以不能直接拉环.
    我不会告诉你因为这个我爆了10发CF
    代码如下

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<cmath>
    #include<vector>
    #include<set>
    #define N (400010)
    #define M (600010)
    #define inf (0x7f7f7f7f)
    #define rg register int
    #define Label puts("NAIVE")
    #define spa print(' ')
    #define ent print('
    ')
    #define rand() (((rand())<<(15))^(rand()))
    typedef long double ld;
    typedef long long LL;
    typedef unsigned long long ull;
    using namespace std;
    inline char read(){
    	static const int IN_LEN=1000000;
    	static char buf[IN_LEN],*s,*t;
    	return (s==t?t=(s=buf)+fread(buf,1,IN_LEN,stdin),(s==t?-1:*s++):*s++);
    }
    template<class T>
    inline void read(T &x){
    	static bool iosig;
    	static char c;
    	for(iosig=false,c=read();!isdigit(c);c=read()){
    		if(c=='-')iosig=true;
    		if(c==-1)return;
    	}
    	for(x=0;isdigit(c);c=read())x=((x+(x<<2))<<1)+(c^'0');
    	if(iosig)x=-x;
    }
    inline char readchar(){
    	static char c;
    	for(c=read();!isalpha(c);c=read())
    	if(c==-1)return 0;
    	return c;
    }
    const int OUT_LEN = 10000000;
    char obuf[OUT_LEN],*ooh=obuf;
    inline void print(char c) {
    	if(ooh==obuf+OUT_LEN)fwrite(obuf,1,OUT_LEN,stdout),ooh=obuf;
    	*ooh++=c;
    }
    template<class T>
    inline void print(T x){
    	static int buf[30],cnt;
    	if(x==0)print('0');
    	else{
    		if(x<0)print('-'),x=-x;
    		for(cnt=0;x;x/=10)buf[++cnt]=x%10+48;
    		while(cnt)print((char)buf[cnt--]);
    	}
    }
    inline void flush(){fwrite(obuf,1,ooh-obuf,stdout);}
    struct xds{
    	int l,r,mi;
    }a[N<<3];
    int F[N],Ne[M<<1],B[M<<1];
    multiset<int> S[N];
    multiset<int>::iterator it;
    bool ins[N];
    int n,m,w[N],fi[N],ne[M<<1],b[M<<1],fa[N],top[N],siz[N],son[N];
    int dfn[N],low[N],ind,rdfn[N],cnt,E,dep[N],Q,E2,st[N],tp;
    void add(int x,int y){
    	ne[++E]=fi[x],fi[x]=E,b[E]=y;
    	ne[++E]=fi[y],fi[y]=E,b[E]=x;
    }
    void add2(int x,int y){
    	Ne[++E2]=F[x],F[x]=E2,B[E2]=y;
    }
    void dfs1(int u,int pre){
    	fa[u]=pre,siz[u]=1;
    	for(int i=fi[u];i;i=ne[i]){
    		int v=b[i];
    		if(v==pre)continue;
    		dep[v]=dep[u]+1,dfs1(v,u),siz[u]+=siz[v];
    		if(siz[v]>siz[son[u]])son[u]=v; 
    	}
    	if(u>n){
    		for(int i=fi[u];i;i=ne[i])
    		if(b[i]!=pre)S[u].insert(w[b[i]]);
    	}
    }
    void dfs2(int u){
    	dfn[u]=++ind,rdfn[ind]=u;
    	if(son[u])top[son[u]]=top[u],dfs2(son[u]);
    	for(int i=fi[u];i;i=ne[i]){
    		int v=b[i];
    		if(v!=fa[u]&&v!=son[u])
    		top[v]=v,dfs2(v);
    	}
    }
    void tarjan(int u,int pre){
    	dfn[u]=low[u]=++ind;
    	fa[u]=pre,st[++tp]=u;
    	for(int i=F[u];i;i=Ne[i]){
    		int v=B[i];
    		if(!dfn[v]){
    			tarjan(v,u),low[u]=min(low[u],low[v]);
    			if(low[v]>=dfn[u]){
    				add(++cnt,u);
    				while(st[tp+1]!=v)add(st[tp],cnt),tp--;
    			}
    		}
    		low[u]=min(low[u],dfn[v]);
    	}
    }
    void build(int l,int r,int x){
    	a[x].l=l,a[x].r=r;
    	if(l==r){
    		int u=rdfn[l];
    		if(u<=n)a[x].mi=w[u];
    		else a[x].mi=*S[u].begin();
    		return;
    	}
    	int mid=(l+r)>>1;
    	build(l,mid,x*2),build(mid+1,r,x*2+1);
    	a[x].mi=min(a[x*2].mi,a[x*2+1].mi);
    }
    void change(int k,int v,int x){
    	if(a[x].l==a[x].r){
    		a[x].mi=v;
    		return;
    	}
    	int mid=(a[x].l+a[x].r)>>1;
    	if(k<=mid)change(k,v,x*2);
    	else change(k,v,x*2+1);
    	a[x].mi=min(a[x*2].mi,a[x*2+1].mi);
    }
    void modify(int x,int val){
    	int ff=fa[x],pmin;
    	change(dfn[x],val,1);
    	if(ff>n){
    		pmin=*S[ff].begin();
    		it=S[ff].find(w[x]);
    		if(it!=S[ff].end())S[ff].erase(it);
    		S[ff].insert(val);
    		int nmin=*S[ff].begin();
    		if(nmin!=pmin)change(dfn[ff],nmin,1);
    	}
    	w[x]=val;
    }
    int query(int l,int r,int x){
    	if(a[x].l==l&&a[x].r==r)return a[x].mi;
    	int mid=(a[x].l+a[x].r)>>1;
    	if(r<=mid)return query(l,r,x*2);
    	else if(l>mid)return query(l,r,x*2+1);
    	else return min(query(l,mid,x*2),query(mid+1,r,x*2+1));
    }
    int query(int u,int v){
    	int ans=inf;
    	while(top[u]!=top[v]){
    		if(dep[top[u]]<dep[top[v]])swap(u,v);
    		ans=min(ans,query(dfn[top[u]],dfn[u],1));
    		u=fa[top[u]];
    	}
    	if(dep[u]>dep[v])swap(u,v);
    	ans=min(ans,query(dfn[u],dfn[v],1));
    	if(u>n)ans=min(ans,w[fa[u]]);
    	return ans;
    }
    int main(){
    	read(n),read(m),read(Q),cnt=n;
    	for(int i=1;i<=n;i++)read(w[i]);
    	for(int i=1,x,y;i<=m;i++){
    		read(x),read(y);
    		add2(x,y),add2(y,x);
    	}
    	tarjan(1,0),ind=0,dfs1(1,0),top[1]=1,dfs2(1),fa[1]=1;
    	build(1,cnt,1);
    	while(Q--){
    		char ch=readchar();
    		int x,y; read(x),read(y);
    		if(ch=='A')print(query(x,y)),ent;
    		else modify(x,y);
    	}
    	return flush(),0;
    }
    
  • 相关阅读:
    sp2010 升级sp2013 用户无法打开网站
    powerviot install in sharepoint 2013
    can not connect cube in performancce dashboard
    westrac server security configure user info
    添加报表服务在多服务器场
    sharepoint 2013 office web app 2013 文档在线浏览 IE11 浏览器不兼容解决方法
    delete job definition
    目前付款申请单内网打开慢的问题
    item style edit in sharepoint 2013
    Could not load file or assembly '$SharePoint.Project.AssemblyFullName$'
  • 原文地址:https://www.cnblogs.com/Romeolong/p/10057413.html
Copyright © 2011-2022 走看看