• 洛谷P3588 [POI2015]PUS(线段树优化建图)


    题面

    传送门

    题解

    先考虑暴力怎么做,我们把所有(r-l+1-k)中的点向(x)连有向边,表示(x)必须比它们大,那么如果这张图有环显然就无解了,否则的话我们跑一个多源最短路,每个点的(dis)就是它的答案

    然而这里边数太多了,所以得线段树优化建边

    //minamoto
    #include<bits/stdc++.h>
    #define R register
    #define ls (p<<1)
    #define rs (p<<1|1)
    #define fp(i,a,b) for(R int i=(a),I=(b)+1;i<I;++i)
    #define fd(i,a,b) for(R int i=(a),I=(b)-1;i>I;--i)
    #define go(u) for(int i=head[u],v=e[i].v;i;i=e[i].nx,v=e[i].v)
    template<class T>inline bool cmax(T&a,const T&b){return a<b?a=b,1:0;}
    using namespace std;
    char buf[1<<21],*p1=buf,*p2=buf;
    inline char getc(){return p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++;}
    int read(){
        R int res,f=1;R char ch;
        while((ch=getc())>'9'||ch<'0')(ch=='-')&&(f=-1);
        for(res=ch-'0';(ch=getc())>='0'&&ch<='9';res=res*10+ch-'0');
        return res*f;
    }
    char sr[1<<21],z[20];int C=-1,Z=0;
    inline void Ot(){fwrite(sr,1,C+1,stdout),C=-1;}
    void print(R int x){
        if(C>1<<20)Ot();if(x<0)sr[++C]='-',x=-x;
        while(z[++Z]=x%10+48,x/=10);
        while(sr[++C]=z[Z],--Z);sr[++C]=' ';
    }
    const int N=5e5+5,M=1e7+5,lim=1e9;
    struct eg{int v,nx,w;}e[M];int head[N],deg[N],tot;
    inline void add(R int u,R int v,R int w){e[++tot]={v,head[u],w},head[u]=tot,++deg[v];}
    int vis[N],dis[N],dfn[N],a[N],q[N];
    int cnt,n,s,m,h,t;
    void build(int p,int l,int r){
    	if(l==r)return dfn[p]=l,void();
    	int mid=(l+r)>>1;dfn[p]=++cnt;
    	build(ls,l,mid),build(rs,mid+1,r);
    	add(dfn[ls],dfn[p],0),add(dfn[rs],dfn[p],0);
    }
    void link(int p,int l,int r,int ql,int qr,int x){
    	if(ql<=l&&qr>=r)return add(dfn[p],x,0),void();
    	int mid=(l+r)>>1;
    	if(ql<=mid)link(ls,l,mid,ql,qr,x);
    	if(qr>mid)link(rs,mid+1,r,ql,qr,x);
    }
    int main(){
    //	freopen("testdata.in","r",stdin);
    	cnt=n=read(),s=read(),m=read();
    	build(1,1,n);
    	for(R int i=1,k,x;i<=s;++i)k=read(),x=read(),a[k]=dis[k]=x;
    	for(R int T=1,l,r,k,las,x;T<=m;++T){
    		l=read(),r=read(),k=read(),las=l-1,++cnt;
    		while(k--)x=read(),add(cnt,x,1),(x>las+1)?(link(1,1,n,las+1,x-1,cnt),0):0,las=x;
    		x<r?(link(1,1,n,x+1,r,cnt),0):0;
    	}
    	h=1,t=0;
    	fp(i,1,cnt)!dis[i]?dis[i]=1:0,!deg[i]?q[++t]=i:0;
    	while(h<=t){
    		int u=q[h++];vis[u]=1;
    		go(u)if(cmax(dis[v],dis[u]+e[i].w),!--deg[v]?q[++t]=v:0,a[v]&&dis[v]>a[v])return puts("NIE"),0;
    	}
    	fp(i,1,cnt)if(!vis[i]||dis[i]>lim)return puts("NIE"),0;
    	puts("TAK");
    	fp(i,1,n)print(dis[i]);
    	return Ot(),0;
    }
    
  • 相关阅读:
    致命错误 RC1004: 文件查找结束时有无法预知的错误(vc++)
    demo713总结
    图标,鼠标,字符串,音频..
    不同的色深条件(8、16、24、32),像素绘制方式
    SQL 保留两位小数的实现方式
    MVC4的REmote缺陷
    MVC4安装过程
    mongodb 的几种驱动
    iis7 web配置问题及解决办法
    Fast Binary File Reading with C#
  • 原文地址:https://www.cnblogs.com/bztMinamoto/p/10555370.html
Copyright © 2020-2023  润新知