zoukankan      html  css  js  c++  java
  • 【2019.9.16】Za

    天天爱跑步

    树上差分

    咕==

    #include<bits/stdc++.h>
    using namespace std;
    const int N=3e5+10,M=50000+10,inf=0x3f3f3f3f;
    int n,m,w[N],ans[N],c1[N<<1],c2[N<<1];
    vector<int>a1[N],b1[N],a2[N],b2[N];
    template <class t>void rd(t &x){
        x=0;int w=0;char ch=0;
        while(!isdigit(ch)) w|=ch=='-',ch=getchar();
        while(isdigit(ch)) x=(x<<1)+(x<<3)+(ch^48),ch=getchar();
        x=w?-x:x;
    }
    
    int head[N],tot=0;
    struct edge{int v,nxt;}e[N<<1];
    void add(int u,int v){e[++tot]=(edge){v,head[u]},head[u]=tot;}
    int dep[N],f[N][25];
    void bfs(int u,int fa){
    	dep[u]=dep[fa]+1,f[u][0]=fa;
    	for(int i=head[u],v;i;i=e[i].nxt)
    	if((v=e[i].v)!=fa) bfs(v,u);
    }
    void prepare(){
    	bfs(1,0);
    	for(int i=1;i<=20;++i)
    		for(int j=1;j<=n;++j)
    			f[j][i]=f[f[j][i-1]][i-1];
    }
    int LCA(int x,int y){
    	if(dep[x]<dep[y]) swap(x,y);
    	for(int i=20;i>=0;--i)
    		if(dep[f[x][i]]>=dep[y]) x=f[x][i];
    	if(x==y) return x;
    	for(int i=20;i>=0;--i)
    	if(f[x][i]!=f[y][i]) x=f[x][i],y=f[y][i];
    	return f[x][0];
    }
    
    bool vis[N];
    void dfs(int x){
    	int w1=c1[dep[x]+w[x]],w2=c2[w[x]-dep[x]+n];
    	vis[x]=1;
    	for(int i=head[x],v;i;i=e[i].nxt)
    	if(!vis[v=e[i].v]) dfs(v);
        for(int i=0;i<a1[x].size();++i) ++c1[a1[x][i]];
        for(int i=0;i<b1[x].size();++i) --c1[b1[x][i]];
        for(int i=0;i<a2[x].size();++i) ++c2[a2[x][i]+n];
        for(int i=0;i<b2[x].size();++i) --c2[b2[x][i]+n];
        ans[x]+=c1[dep[x]+w[x]]-w1+c2[w[x]-dep[x]+n]-w2;
    }
    
    
    int main(){
    	freopen("in.txt","r",stdin);
    	rd(n),rd(m);
    	for(int i=1,u,v;i<n;++i) rd(u),rd(v),add(u,v),add(v,u);
    	for(int i=1;i<=n;++i) rd(w[i]);
    	prepare();
    	for(int i=1,x,y,z;i<=m;++i){
    		rd(x),rd(y),z=LCA(x,y);
    		a1[x].push_back(dep[x]),
    		a2[y].push_back(dep[x]-(dep[z]<<1)),
    		b1[f[z][0]].push_back(dep[x]),
    		b2[z].push_back(dep[x]-(dep[z]<<1));
    	}
    	dfs(1);
    	for(int i=1;i<=n;++i) printf("%d ",ans[i]);
    	return 0;
    }
    

    求桥

    void tarjan(int u,int ine){
        dfn[u]=low[u]=++idx;
        for(int i=head[u],v;i;i=e[i].nxt){
    		if(!dfn[v=e[i].v]) {
    			tarjan(v,i),low[u]=min(low[u],low[v]);
                if(low[v]>dfn[u]) bridge[i]=bridge[i^1]=1;
        	}
            else if(i!=(ine^1)) low[u]=min(low[u],dfn[v]);
    	}
    }
    

    求割点

    void tarjan(int u){
        dfn[u]=low[u]=++idx;int kid=0;
        for(int i=head[u],v;i;i=e[i].nxt){
            if(!dfn[v=e[i].v]){
    			tarjan(v),low[u]=min(low[u],low[v]);
                if(low[v]>=dfn[u])
                    if(++kid>1||u!=rt) cut[u]=1;
            }
            else low[u]=min(low[u],dfn[v]);
        }
    }
    

    边双连通e-DCC

    void tarjan(int u,int ine){
        dfn[u]=low[u]=++idx;
        for(int i=head[u],v;i;i=e[i].nxt){
    		if(!dfn[v=e[i].v]) {
    			tarjan(v,i),low[u]=min(low[u],low[v]);
                if(low[v]>dfn[u]) bridge[i]=bridge[i^1]=1;
        	}
            else if(i!=(ine^1)) low[u]=min(low[u],dfn[v]);
    	}
    }
    int bl[N],dcc;
    void dfs(int x){
    	bl[x]=dcc;
        for(int i=head[u],v;i;i=e[i].nxt)
            if(!bl[v=e[i].v]&&!bridge[i]) dfs(v);
    }
    int main(){
        for(int i=1;i<=n;++i)
            if(!bl[i]) ++dcc,dfs(i);
    	return 0;
    }
    

    点双连通v-DCC

    void tarjan(int u){
        dfn[u]=low[u]=++idx,s.push(u);
        if(u==rt&&!head[u]) dcc[++cnt].push_back(u);
        int kid=0;
        for(int i=head[u],v,;i;i=e[i].nxt){
            if(!dfn[v=e[i].v]){
                tarjan(v),low[u]=min(low[u],low[v]);
                if(low[v]>=low[u]){
                    if(++kid>1||u!=rt) cut[u]=1;
                    ++cnt;int z;
                    do{
                        z=s.top(),s.pop();
                        dcc[cnt].push_back(z);
    				}while(z!=v)
                        dcc[cnt].push_back(u);
    			}
                else low[u]=min(low[u],dfn[v]);
            }
    	}
    }
    

    [JSOI2010] 连通数

    bzoj2208 luogu4306

    缩点完后用bitset来统计==

    按拓扑序来

    #include<bits/stdc++.h>
    using namespace std;
    #define Max(x,y) ((x)>(y)?(x):(y))
    #define Min(x,y) ((x)<(y)?(x):(y))
    const int N=2000+10,M=4000000+10,inf=0x3f3f3f3f;
    int n;
    char ss[N];
    bitset<N>f[N];
    template <class t>void rd(t &x){
        x=0;int w=0;char ch=0;
        while(!isdigit(ch)) w|=ch=='-',ch=getchar();
        while(isdigit(ch)) x=(x<<1)+(x<<3)+(ch^48),ch=getchar();
        x=w?-x:x;
    }
    
    int head[N],hd[N],tot=0,tt=0;
    struct edge{int v,nxt;}e[M],E[M];
    void Add(int u,int v){E[++tt]=(edge){v,hd[u]},hd[u]=tt;}
    void add(int u,int v){e[++tot]=(edge){v,head[u]},head[u]=tot;}
    
    int idx=0,Bcnt=0,dfn[N],low[N],bl[N],sz[N];
    stack<int>s;bool inst[N];
    void tarjan(int u){
        dfn[u]=low[u]=++idx,s.push(u),inst[u]=1;
        for(int i=head[u],v;i;i=e[i].nxt)
            if(!dfn[v=e[i].v]) tarjan(v),low[u]=Min(low[u],low[v]);
            else if(inst[v]&&dfn[v]<low[u]) low[u]=dfn[v];
        if(dfn[u]==low[u]){
            ++Bcnt;int v;
            do{
                v=s.top(),s.pop(),inst[v]=0,f[Bcnt].set(v);
                bl[v]=Bcnt,++sz[Bcnt];
            }while(u!=v);
        }
    }
    
    int Q[N],in[N];
    queue<int>q;
    void topsort(){
    	for(int i=1;i<=Bcnt;++i) if(!in[i]) q.push(i);
    	while(!q.empty()){
    		int u=q.front();
    		q.pop(),Q[++Q[0]]=u;
    		for(int i=hd[u],v;i;i=E[i].nxt)
    			if(!--in[v=E[i].v]) q.push(v);
    	}
    	for(int i=Q[0];i;--i)
    		for(int j=hd[Q[i]];j;j=E[j].nxt)
    			f[Q[i]]|=f[E[j].v];
    }
    
    int main(){
    	freopen("in.txt","r",stdin);
    	rd(n);
    	for(int i=1;i<=n;++i){
    		scanf("%s",ss+1);
    		for(int j=1;j<=n;++j)
    			if(ss[j]=='1') add(i,j);
    	}
    	for(int i=1;i<=n;++i)
    	if(!dfn[i]) tarjan(i);
    	for(int u=1,v;u<=n;++u)
    		for(int i=head[u];i;i=e[i].nxt)
    			if(bl[u]!=bl[v=e[i].v]) Add(bl[u],bl[v]),++in[bl[v]];
    	int ans=0;
    	topsort();
    	for(int i=1;i<=Bcnt;++i) ans+=f[i].count()*sz[i];
    	printf("%d",ans);
    	return 0;
    }
    

    缩完点后topsort时DP

    #include<bits/stdc++.h>
    using namespace std;
    #define Max(x,y) ((x)>(y)?(x):(y))
    #define Min(x,y) ((x)<(y)?(x):(y))
    const int N=100000+10,M=100000 +10,inf=0x3f3f3f3f;
    int n,m,in[N];
    template <class t>void rd(t &x){
        x=0;int w=0;char ch=0;
        while(!isdigit(ch)) w|=ch=='-',ch=getchar();
        while(isdigit(ch)) x=(x<<1)+(x<<3)+(ch^48),ch=getchar();
        x=w?-x:x;
    }
    
    int head[N],hd[N],tot=0,tt=0;
    struct edge{int v,w,nxt;}e[M],E[M<<1];
    void Add(int u,int v,int w){E[++tt]=(edge){v,w,hd[u]},hd[u]=tt;}
    void add(int u,int v,int w){e[++tot]=(edge){v,w,head[u]},head[u]=tot;}
    int idx=0,Bcnt=0,dfn[N],low[N],bl[N],sz[N];
    stack<int>s;bool inst[N];
    void tarjan(int u){
    	dfn[u]=low[u]=++idx,s.push(u),inst[u]=1;
    	for(int i=head[u],v;i;i=e[i].nxt)
    		if(!dfn[v=e[i].v]) tarjan(v),low[u]=Min(low[u],low[v]);
    		else if(inst[v]&&dfn[v]<low[u]) low[u]=dfn[v];
    	if(low[u]==dfn[u]){
    		++Bcnt;int v;
    		do{
    			v=s.top(),s.pop(),inst[v]=0;
    			bl[v]=Bcnt,++sz[Bcnt];
    		}while(u!=v);
    	}
    }
    
    queue<int>q;
    int f[N];
    void topsort(){
    	q.push(0);
    	while(!q.empty()){
    		int u=q.front();q.pop();
    		for(int i=hd[u],v;i;i=E[i].nxt){
    			f[v=E[i].v]=Max(f[v],f[u]+E[i].w);
    			if(!--in[v]) q.push(v);
    		}
    	}
    	long long ans=0;
    	for(int i=1;i<=Bcnt;++i) ans+=(long long)f[i]*sz[i];
    	printf("%lld",ans);
    }
    
    int main(){
    	freopen("in.txt","r",stdin);
    	rd(n),rd(m);
    	for(int i=1,opt,x,y;i<=m;++i){
    		rd(opt),rd(x),rd(y);
    		if(opt==1) add(x,y,0),add(y,x,0);
    		else if(opt==2) add(x,y,1);
    		else if(opt==3) add(y,x,0);
    		else if(opt==4) add(y,x,1);
    		else add(x,y,0);
    	}
    	for(int i=1;i<=n;++i) if(!dfn[i]) tarjan(i);
    	for(int u=1;u<=n;++u)
    		for(int i=head[u],v;i;i=e[i].nxt){
    			if(bl[u]==bl[v=e[i].v]&&e[i].w) return puts("-1"),0;
    			else if(bl[u]!=bl[v]) Add(bl[u],bl[v],e[i].w),++in[bl[v]];
    		}
    	for(int i=1;i<=Bcnt;++i) Add(0,i,1),++in[i];
    	topsort();
    	return 0;
    }
    

    [IOI2008]Island

    我太难了 打的时候脑子里一团浆糊

    acwing上面要T 洛谷上面可以过

    #include<bits/stdc++.h>
    using namespace std;
    #define Max(x,y) ((x)>(y)?(x):(y))
    #define Min(x,y) ((x)<(y)?(x):(y))
    #define ll long long
    const int N=1e6+10,M=100000 +10,inf=0x3f3f3f3f;
    int n,in[N];
    template <class t>void rd(t &x){
        x=0;int w=0;char ch=0;
        while(!isdigit(ch)) w|=ch=='-',ch=getchar();
        while(isdigit(ch)) x=(x<<1)+(x<<3)+(ch^48),ch=getchar();
        x=w?-x:x;
    }
    
    int head[N],tot=0;
    struct edge{int v,w,nxt;}e[N<<1];
    void add(int u,int v,int w){
    	e[++tot]=(edge){v,w,head[u]},head[u]=tot,++in[v];
    }
    
    int bl[N],Bcnt=0;
    queue<int>q;
    void bfs(int u){
    	q.push(u);
    	while(!q.empty()){
    		u=q.front(),q.pop();
    		for(int i=head[u],v;i;i=e[i].nxt)
    			if(!bl[v=e[i].v]) bl[v]=Bcnt,q.push(v);
    	}
    }
    
    ll dis[N],f[N],a[N],b[N];
    void topsort(){
    	for(int i=1;i<=n;++i) if(in[i]==1) q.push(i);
    	while(!q.empty()){
    		int u=q.front();q.pop();
    		for(int i=head[u],v;i;i=e[i].nxt)
    		if(in[v=e[i].v]>1){
    			dis[bl[u]]=Max(dis[bl[u]],f[u]+f[v]+e[i].w),
    			f[v]=Max(f[v],f[u]+e[i].w);
    			if((--in[v])==1) q.push(v);
    		}
    	}
    }
    
    int Q[N];
    bool vis[N];
    void dp(int x,int t)
    {
    	int m=0,i,l=0,r,y=x;
    	do{
    		a[++m]=f[y];in[y]=1;
    		for(i=head[y];i;i=e[i].nxt)
    			if(in[e[i].v]>1)
    				{y=e[i].v;b[m+1]=b[m]+e[i].w; break;}
    	}while(i);
    	if(m==2)
    	{
    		for(i=head[y];i;i=e[i].nxt)
    			if(e[i].v==x) {l=max(l,e[i].w);}
    		dis[t]=max(dis[t],f[x]+f[y]+l);
    		return;
    	}
    	for(i=head[y];i;i=e[i].nxt)
    		if(e[i].v==x) {b[m+1]=b[m]+e[i].w; break;}
    	for(i=1;i<m;i++) {a[m+i]=a[i]; b[m+i]=b[m+1]+b[i];}
    	Q[l=r=1]=1;
    	for(i=2;i<2*m;i++)
    	{
    		while(l<=r&&i-Q[l]>=m) l++;
    		dis[t]=max(dis[t],a[i]+a[Q[l]]+b[i]-b[Q[l]]);
    		while(l<=r&&a[Q[r]]+b[i]-b[Q[r]]<=a[i]) r--;
    		Q[++r]=i;
    	}
    }
    
    
    int main(){
    	freopen("in.txt","r",stdin);
    	rd(n);ll ans=0;
    	for(int i=1,v,w;i<=n;++i) rd(v),rd(w),add(i,v,w),add(v,i,w);
    	for(int i=1;i<=n;++i)
    	if(!bl[i]) ++Bcnt,bfs(i);
    	topsort();
    	for(int i=1;i<=n;++i)
    	if(in[i]>1&&!vis[bl[i]]) vis[bl[i]]=1,dp(i,bl[i]),ans+=dis[bl[i]];
    	printf("%lld",ans);
    	return 0;
    }
    
  • 相关阅读:
    SQLServer 知识点
    Entity转换为ViewModel时提供的一种转换方法
    Linq中IGrouping转换为IQueryable
    封装整形属性时对应到枚举
    新的转换列表方式
    工作态度
    EasyFrame
    NewCloud
    将博客搬至CSDN
    Html的语义化
  • 原文地址:https://www.cnblogs.com/lxyyyy/p/11552927.html
Copyright © 2011-2022 走看看