BZOJ4383[POI2015]pustynia
题意:
有(N)个正整数,每个数都小于(10^9),已知初始给你的(S)个数,以及(M)个限制,第(i)个限制给你一个区间(L_isim R_i)和(K_i)个位置,表示这个区间内,这(K_i)个位置上的数大于任意剩下的(R_i-L_i+1-K_i)个位置上的数。求可行方案。((N,Sle 10^5,Mle 2*10^5))
题解:
果断差分约束啊,线段树或(ST)表优化建边。完了。(随便卡边的空间啊,我咋过的
#include<queue>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define fo(i,l,r) for(int i=l;i<=r;i++)
#define of(i,l,r) for(int i=l;i>=r;i--)
#define fe(i,u) for(int i=head[u];i;i=e[i].next)
#define idn(o) (o)
#define idm(o) (n+o)
#define idt(o) (n+m+o)
using namespace std;
typedef long long ll;
inline int rd()
{
static int x,f;
x=0,f=1;
char ch=getchar();
for(;ch<'0'||ch>'9';ch=getchar())if(ch=='-')f=-1;
for(;ch>='0'&&ch<='9';ch=getchar())x=x*10+ch-'0';
return x*f;
}
const int N=100010,M=200010;
struct edge{
int v,w,next;
edge(int v=0,int w=0,int next=0):v(v),w(w),next(next){}
}e[3000010];
int n,s,m,rt;
int tot=0,head[1000010];
int a[1000010],in[1000010];
bool f[1000010];
inline void add(int u,int v,int w){e[++tot]=edge(v,w,head[u]);head[u]=tot;in[v]++;}
namespace Seg{
#define lson tr[o].ls,l,mid
#define rson tr[o].rs,mid+1,r
struct tree{
int ls,rs;
}tr[N<<1];
int cnt=0;
void build(int &o,int l,int r)
{
o=++cnt;
if(l==r)return add(idn(l),idt(o),0);
int mid=(l+r)>>1;
build(lson);build(rson);
add(idt(tr[o].ls),idt(o),0);
add(idt(tr[o].rs),idt(o),0);
}
void gao(int o,int l,int r,int L,int R,int x)
{
if(L>R)return;
if(l==L&&r==R)return add(idt(o),x,0);
int mid=(l+r)>>1;
if(L<=mid)gao(lson,L,min(mid,R),x);
if(R>mid)gao(rson,max(mid+1,L),R,x);
}
}
inline void pre()
{
Seg::build(rt,1,n);
fo(i,1,m){
int l=rd(),r=rd(),k=rd();
int x,y=l-1;
fo(j,1,k){
x=rd();
add(idm(i),idn(x),1);
Seg::gao(rt,1,n,y+1,x-1,idm(i));
y=x;
}
Seg::gao(rt,1,n,x+1,r,idm(i));
}
}
queue<int>q;
inline int toposort()
{
fo(i,1,n){
if(!in[idn(i)])q.push(idn(i));
if(!f[idn(i)])a[idn(i)]=1;
}
int t=0;
while(!q.empty()){
int u=q.front();q.pop();
t++;if(a[u]>1000000000)return puts("NIE");
fe(i,u){
int v=e[i].v,w=e[i].w;
if(f[v]&&a[v]<a[u]+w)return puts("NIE");
a[v]=max(a[v],a[u]+w);
if(!--in[v])q.push(v);
}
}
if(t<n+m+Seg::cnt)return puts("NIE");
puts("TAK");
fo(i,1,n)printf("%d ",a[idn(i)]);puts("");
return 0;
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("in.txt","r",stdin);
freopen("out.txt","w",stdout);
#endif
n=rd();s=rd();m=rd();
fo(i,1,s){
int x=rd();
a[idn(x)]=rd(),f[idn(x)]=1;
}
pre();
toposort();
return 0;
}