题目描述
Description
Input
Output
若无解,则输出”Impossible”。
否则第一行输出”Possible”,第二行输出 n 个正整数,依次输出序列 a 中每个数。
Sample Input
5 2 2
2 7
5 3
1 4 2 2 3
4 5 1 4
Sample Output
Possible
6 7 1000000000 6 3
Data Constraint
题解
线段树优化连边
ki向xij连边,xi与xi+1间的点向ki连边(线段树),线段树的点从下往上连边
一条从u到v的权值为s的边的意义是f[u]+s<=f[v],拓扑求max即可
初值就是给出的p和d(不需要求出相对大小然后再搞)
code
#include <algorithm> #include <iostream> #include <cstdlib> #include <cstring> #include <cstdio> #define fo(a,b,c) for (a=b; a<=c; a++) #define fd(a,b,c) for (a=b; a>=c; a--) #define min(a,b) (a<b?a:b) #define max(a,b) (a>b?a:b) using namespace std; struct type{ int s,x; } b[100001]; int a[5000001][3]; int D[1000001]; int ls[1000001]; int d[1000001]; int f[1000001]; int F[1000001]; int c[100002]; int N,n,s,m,i,j,k,l,len,L,R,tot,h,t,mx; void New(int x,int y,int z) { ++len; a[len][0]=y; a[len][1]=ls[x]; ls[x]=len; a[len][2]=z; ++D[y]; } void mt(int t,int l,int r) { int mid=(l+r)/2; N=max(N,t+n); if (l==r) return; mt(t*2,l,mid); if (l<mid) New(t*2+n,t+n,0); else New(l,t+n,0); mt(t*2+1,mid+1,r); if (mid+1<r) New(t*2+1+n,t+n,0); else New(r,t+n,0); } void work(int t,int l,int r,int x,int y) { int mid=(l+r)/2; if (x<=l && r<=y) { if (l==r) New(l,N,1); else New(t+n,N,1); return; } if (x<=mid) work(t*2,l,mid,x,y); if (mid<y) work(t*2+1,mid+1,r,x,y); } int main() { freopen("web.in","r",stdin); freopen("web.out","w",stdout); scanf("%d%d%d",&n,&s,&m); fo(i,1,n) f[i]=1; fo(i,1,s) scanf("%d%d",&b[i].x,&b[i].s),f[b[i].x]=b[i].s,F[b[i].x]=b[i].s; mt(1,1,n); fo(i,1,m) { ++N; scanf("%d%d%d",&L,&R,&tot); fo(j,1,tot) { scanf("%d",&c[j]); New(N,c[j],0); } c[0]=L-1; c[++tot]=R+1; fo(j,1,tot) if (c[j-1]+1<=c[j]-1) work(1,1,n,c[j-1]+1,c[j]-1); } h=0;t=0; fo(i,1,N) if (!D[i]) d[++t]=i; while (h<t) { for (i=ls[d[++h]]; i; i=a[i][1]) { f[a[i][0]]=max(f[a[i][0]],f[d[h]]+a[i][2]); if (F[a[i][0]] && f[a[i][0]]>F[a[i][0]]) { printf("Impossible\n"); return 0; } --D[a[i][0]]; if (!D[a[i][0]]) d[++t]=a[i][0]; } } if (t<N) { printf("Impossible\n"); return 0; } else { printf("Possible\n"); fo(i,1,n) printf("%d ",f[i]); printf("\n"); } fclose(stdin); fclose(stdout); return 0; }