是个很裸的差分约束?
如果有限制x>y
可以连一条边x->y,-1
代表y<=x-1 即 x>y
注意到k个数把区间划分成了k个区间,对于每个限制,新建一个点,k个特殊的数向其连边-1,它向k个区间连边0
线段树优化建图
建好图后如果不是DAG说明有负环,无解
否则是个DAG,令f[x]表示x最大能取到的值,dp f值
如果一个固定了值的位置,他的f值< 它的值,也无解
code:
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define ll long long
using namespace std;
inline void up(int &x,const int &y){if(xinline void down(int &x,const int &y){if(x>y)x=y;}
const int maxn = 210000;
const int maxm = 210000;
const int maxk = 300005;
int n,s,m,N;
int c[maxn];
struct edge{int y,c,nex;}a[maxk*20]; int len,fir[maxn*4+maxm],in[maxn*4+maxm];
inline void ins(const int x,const int y,const int c){in[y]++;a[++len]=(edge){y,c,fir[x]};fir[x]=len;}
int To[maxn<<2],tr[maxn];
void build(const int x,const int l,const int r)
{
up(N,x);
if(l==r) {tr[To[x]=l]=x; return;}
int mid=l+r>>1,lc=x<<1,rc=lc|1;
ins(x,lc,0); ins(x,rc,0);
build(lc,l,mid); build(rc,mid+1,r);
}
int lx,rx,now;
void link(const int x,const int l,const int r)
{
if(rxreturn;
if(lx<=l&&r<=rx) { ins(now,x,0); return; }
int mid=l+r>>1,lc=x<<1,rc=lc|1;
link(lc,l,mid); link(rc,mid+1,r);
}
int f[maxn*4+maxm];
queue<int>q;
bool solve()
{
for(int i=1;i<=N+m;i++)
{
f[i]=1e9;
if(!in[i]) q.push(i);
}
while(!q.empty())
{
const int x=q.front(); q.pop();
if(c[To[x]]!=-1)
{
if(f[x]return false;
f[x]=c[To[x]];
}
for(int k=fir[x],y=a[k].y;k;k=a[k].nex,y=a[k].y)
{
down(f[y],f[x]+a[k].c);
in[y]--; if(!in[y]) q.push(y);
}
}
for(int i=1;i<=N;i++)
{
if(in[i]||f[i]<1) return false;
if(c[To[i]]!=-1) f[i]=c[To[i]];
}
return true;
}
int main()
{
memset(c,-1,sizeof c);
scanf("%d%d%d",&n,&s,&m);
for(int i=1;i<=s;i++)
{
int x,y; scanf("%d%d",&x,&y);
c[x]=y;
}
build(1,1,n);
for(int i=1;i<=m;i++)
{
int l,r,k; scanf("%d%d%d",&l,&r,&k);
int las=l; now=N+i;
while(k--)
{
int x; scanf("%d",&x); ins(tr[x],N+i,-1);
if(las1,link(1,1,n);
las=x+1;
}
if(las<=r) lx=las,rx=r,link(1,1,n);
}
bool flag=solve();
if(!flag) puts("NIE");
else
{
puts("TAK");
for(int i=1;i<=n;i++) printf("%d ",f[tr[i]]);
}
return 0;
}