【BZOJ4383】[POI2015]pustynia

题意:

建议Alt+F4百度一下

题解:

差分约束+线段树优化建图,直接按照拓扑序跑就行了

代码:

 1 #include<iostream>
 2 #include<cstring>
 3 #include<cstdio>
 4 #include<cmath>
 5 #define DCSB {printf("NIE");exit(0);}
 6 using namespace std;
 7 struct node{
 8     int ls,rs,v;
 9 }t[2000001];
10 struct edge{
11     int v,w,next;
12 }a[2000001];
13 int n,m,s,l,r,k,u,v,x,cnt=0,rt,tot=0,q[1000001],head[1000001],num[1000001],f[1000001],in[1000001];
14 void add(int u,int v,int w){
15     a[++tot].v=v;
16     a[tot].w=w;
17     a[tot].next=head[u];
18     head[u]=tot;
19     in[v]++;
20 }
21 void build(int &u,int l,int r){
22     u=++cnt;
23     if(l==r){
24         t[l].v=u;
25         return;
26     }
27     int mid=(l+r)/2;
28     build(t[u].ls,l,mid);
29     build(t[u].rs,mid+1,r);
30     add(t[u].ls,u,0);
31     add(t[u].rs,u,0);
32 }
33 void updata(int u,int l,int r,int L,int R,int v){
34     if(l==L&&r==R){
35         add(u,cnt,v);
36         return;
37     }
38     int mid=(l+r)/2;
39     if(R<=mid)updata(t[u].ls,l,mid,L,R,v);
40     else if(L>mid)updata(t[u].rs,mid+1,r,L,R,v);
41     else{
42         updata(t[u].ls,l,mid,L,mid,v);
43         updata(t[u].rs,mid+1,r,mid+1,R,v);
44     }
45 }
46 void topsort(){
47     int l=0,r=0;
48     for(int i=1;i<=cnt;i++){
49         if(!in[i]){
50             q[++r]=i;
51             f[i]=1;
52         }
53     }
54     while(l<r){
55         int u=q[++l];
56         if(f[u]>1000000000)DCSB
57         if(f[u]>num[u]&&num[u]!=0)DCSB
58         f[u]=max(f[u],num[u]);
59         for(int tmp=head[u];tmp!=-1;tmp=a[tmp].next){
60             int v=a[tmp].v;
61             in[v]--;
62             if(!in[v])q[++r]=v;
63             f[v]=max(f[v],f[u]+a[tmp].w);
64         }
65     }
66     if(r<cnt)DCSB
67 }
68 int main(){
69     memset(head,-1,sizeof(head));
70     scanf("%d%d%d",&n,&s,&m);
71     build(rt,1,n);
72     for(int i=1;i<=s;i++){
73         scanf("%d%d",&u,&v);
74         num[t[u].v]=v;
75     }
76     for(int i=1;i<=m;i++){
77         scanf("%d%d%d",&l,&r,&k);
78         l--,cnt++;
79         for(int j=1;j<=k;j++){
80             scanf("%d",&x);
81             add(cnt,t[x].v,0);
82             if(l+1<x)updata(rt,1,n,l+1,x-1,1);
83             l=x;
84         }
85         if(x<r)updata(rt,1,n,x+1,r,1);
86     }
87     topsort();
88     printf("TAK
");
89     for(int i=1;i<=n;i++)printf("%d ",f[t[i].v]);
90     return 0;
91 }
原文地址:https://www.cnblogs.com/dcdcbigbig/p/9537713.html