cjb-poi2011meteors
从 Trac 迁移的文章
这是从旧校内 Wiki 迁移的文章,可能存在一些样式问题,您可以向 memset0 反馈。
原文章内容如下:
{{{
#include <bits/stdc++.h>
using namespace std;
#define rep(i,n) for(int i=1;i<=n;++i)
#define mp make_pair
#define pb push_back
#define x0 gtmsub
#define y0 gtmshb
#define x1 gtmjtjl
#define y1 gtmsf
const int N=300010;
struct query
{
int l,r,a;
void scan(){scanf("%d%d%d",&l,&r,&a);}
}q[N];
vector<int>g[N];
int need[N],n,m,k;
int ans[N],p[N],tmp1[N],tmp2[N];
long long c[N];
void modify(int x,int y){for(;x<=m;x+=x&(-x))c[x]+=y;}
long long get(int x){long long s=0;for(;x;x-=x&(-x))s+=c[x];return s;}
void clear(int x){for(;x<=m;x+=x&(-x))c[x]=0;}
void modi(const query&a)
{
if(a.l<=a.r)
{
modify(a.l,a.a);
modify(a.r+1,-a.a);
}
else
{
modify(1,a.a);
modify(a.r+1,-a.a);
modify(a.l,a.a);
}
}
void cle(const query&a)
{
if(a.l<=a.r)
{
clear(a.l);
clear(a.r+1);
}
else
{
clear(1);
clear(a.r+1);
clear(a.l);
}
}
void work(int a,int b,int l,int r)
{
if(l==r)
{
for(int i=a;i<=b;i++)ans[p[i]]=l;
return;
}
int mid=(l+r)>>1;
for(int i=l;i<=mid;i++)modi(q[i]);
int cnt1=0,cnt2=0;
for(int i=a;i<=b;i++)
{
long long now=need[p[i]];
for(auto j:g[p[i]])
{
if(now<=0)break;
now-=get(j);
}
if(now<=0)tmp1[++cnt1]=p[i];else tmp2[++cnt2]=p[i],need[p[i]]=now;
}
for(int i=a;i<=b;i++)if(i-a+1<=cnt1)p[i]=tmp1[i-a+1];else p[i]=tmp2[i-a+1-cnt1];
for(int i=l;i<=mid;i++)cle(q[i]);
work(a,a+cnt1-1,l,mid);
work(a+cnt1,b,mid+1,r);
}
int main()
{
freopen("meteors.in","r",stdin);
freopen("meteors.out","w",stdout);
scanf("%d%d",&n,&m);
rep(i,m)
{
int x;
scanf("%d",&x);
g[x].pb(i);
}
rep(i,n)scanf("%d",&need[i]);
scanf("%d",&k);
rep(i,k)q[i].scan();
rep(i,n)p[i]=i;
work(1,n,1,k+1);
rep(i,n)if(ans[i]<=k)printf("%d\n",ans[i]);else puts("NIE");
return 0;
}
}}}
#include <bits/stdc++.h>
using namespace std;
#define rep(i,n) for(int i=1;i<=n;++i)
#define mp make_pair
#define pb push_back
#define x0 gtmsub
#define y0 gtmshb
#define x1 gtmjtjl
#define y1 gtmsf
const int N=300010;
struct query
{
int l,r,a;
void scan(){scanf("%d%d%d",&l,&r,&a);}
}q[N];
vector<int>g[N];
int need[N],n,m,k;
int ans[N],p[N],tmp1[N],tmp2[N];
long long c[N];
void modify(int x,int y){for(;x<=m;x+=x&(-x))c[x]+=y;}
long long get(int x){long long s=0;for(;x;x-=x&(-x))s+=c[x];return s;}
void clear(int x){for(;x<=m;x+=x&(-x))c[x]=0;}
void modi(const query&a)
{
if(a.l<=a.r)
{
modify(a.l,a.a);
modify(a.r+1,-a.a);
}
else
{
modify(1,a.a);
modify(a.r+1,-a.a);
modify(a.l,a.a);
}
}
void cle(const query&a)
{
if(a.l<=a.r)
{
clear(a.l);
clear(a.r+1);
}
else
{
clear(1);
clear(a.r+1);
clear(a.l);
}
}
void work(int a,int b,int l,int r)
{
if(l==r)
{
for(int i=a;i<=b;i++)ans[p[i]]=l;
return;
}
int mid=(l+r)>>1;
for(int i=l;i<=mid;i++)modi(q[i]);
int cnt1=0,cnt2=0;
for(int i=a;i<=b;i++)
{
long long now=need[p[i]];
for(auto j:g[p[i]])
{
if(now<=0)break;
now-=get(j);
}
if(now<=0)tmp1[++cnt1]=p[i];else tmp2[++cnt2]=p[i],need[p[i]]=now;
}
for(int i=a;i<=b;i++)if(i-a+1<=cnt1)p[i]=tmp1[i-a+1];else p[i]=tmp2[i-a+1-cnt1];
for(int i=l;i<=mid;i++)cle(q[i]);
work(a,a+cnt1-1,l,mid);
work(a+cnt1,b,mid+1,r);
}
int main()
{
freopen("meteors.in","r",stdin);
freopen("meteors.out","w",stdout);
scanf("%d%d",&n,&m);
rep(i,m)
{
int x;
scanf("%d",&x);
g[x].pb(i);
}
rep(i,n)scanf("%d",&need[i]);
scanf("%d",&k);
rep(i,k)q[i].scan();
rep(i,n)p[i]=i;
work(1,n,1,k+1);
rep(i,n)if(ans[i]<=k)printf("%d\n",ans[i]);else puts("NIE");
return 0;
}