【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\n");
89 for(int i=1;i<=n;i++)printf("%d ",f[t[i].v]);
90 return 0;
91 }