每次建一个辅助点然后线段树优化建图即可,注意特判 a[i]≤109 a [ i ] ≤ 10 9 .
#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<queue>
#define gc getchar()
#define LEN 100010
#define LOG 20
#define N (LEN*LOG+400010)
#define M (N*2)
#define INF 1000000000
#define debug(x) cerr<<#x<<"="<<x
#define sp <<" "
#define ln <<endl
using namespace std;
inline int inn()
{
int x,ch;while((ch=gc)<'0'||ch>'9');
x=ch^'0';while((ch=gc)>='0'&&ch<='9')
x=(x<<1)+(x<<3)+(ch^'0');return x;
}
struct edges{
int to,pre;
}e[M];int h[N],a[N],Log[LEN],etop,up[LEN][LOG],isf[N],d[N],t[N];queue<int> q;
inline int add_edge(int u,int v) { return e[++etop].to=v,e[etop].pre=h[u],h[u]=etop,d[v]++; }
inline int Add(int x,int s,int t)
{
if(s>t) return 0;int k=Log[t-s+1];
if(s==t) add_edge(x,up[s][0]);
else add_edge(x,up[s][k]),add_edge(x,up[t-(1<<k)+1][k]);
return 0;
}
inline int toposort(int n,int c=0)
{
for(int i=1;i<=n;i++) if(!d[i]) q.push(i);
while(!q.empty())
{
int x=q.front();q.pop(),t[++c]=x;
for(int i=h[x],y;i;i=e[i].pre)
if(!(--d[y=e[i].to])) q.push(y);
}
return 0;
}
int main()
{
int n=inn(),s=inn(),m=inn(),c=n;
for(int i=1,x;i<=s;i++) x=inn(),a[x]=inn();
// for(int i=1;i<=n;i++) debug(i)sp,debug(a[i])ln;
for(int i=2;i<=n;i++) Log[i]=Log[i>>1]+1;
for(int i=1;i<=n;i++) add_edge(up[i][0]=++c,i);
for(int j=1;(1<<j)<=n;j++)
for(int i=1;i+(1<<j)-1<=n;i++)
up[i][j]=++c,add_edge(up[i][j],up[i][j-1]),
add_edge(up[i][j],up[i+(1<<(j-1))][j-1]);
while(m--)
{
int l=inn(),r=inn(),k=inn(),las=l-1,fz=++c,x;
while(k--) x=inn(),add_edge(x,fz),Add(fz,las+1,x-1),las=x;
Add(fz,las+1,r),isf[fz]=1;
}
toposort(c);
for(int i=1;i<=n;i++) if(d[i]) return !printf("NIE\n");
for(int j=c,x;j;j--)
if(a[x=t[j]])
{
for(int i=h[x],y;i;i=e[i].pre)
if(a[x]<a[e[i].to]+isf[e[i].to])
return !printf("NIE\n");
}
else{
if(x<=n) a[x]=1;
for(int i=h[x],y;i;i=e[i].pre)
a[x]=max(a[x],a[e[i].to]+isf[e[i].to]);
}
for(int i=1;i<=n;i++) if(a[i]>INF) return !printf("NIE\n");
printf("TAK\n");
for(int i=1;i<=n;i++) printf("%d ",a[i]);
return !printf("\n");
}