题目:
题解:
对于每个国家来说,求出流星雨是第几次是一个妥妥的二分,但是这么多国家的话,我们用整体二分就行了
我们调用solve(1,k,1,n)就可以解决问题,即[1,k]范围内的流星雨可以解决[1,n]的国家
每次让在[l,mid]范围内的流星雨落下,回溯时要删除,二分询问的时候完成任务的国家放在左边,没完成的放在右边
特别要注意流星雨落下时l和r的大小。。
然后就是要开LL
代码:
#include <cstdio>
#include <algorithm>
#define LL long long
using namespace std;
const int N=300005;
struct hh{int hop,id,num;}st[N];
struct lj{int l,r;LL k;}q[N];
int tot,nxt[N],point[N],v[N],m,n;LL c[N],ans[N];
void addline(int x,int y){++tot; nxt[tot]=point[x]; point[x]=tot; v[tot]=y;}
void add(int loc,LL v){for (int i=loc;i<=m+5;i+=i&(-i)) c[i]+=v;}
LL qurry(int loc)
{
LL ans=0;
for (int i=loc;i>=1;i-=i&(-i)) ans+=c[i];
return ans;
}
int cmp1(hh a,hh b){return a.num<b.num;}
void ef(int l,int r,int a,int b)
{
if (a>b) return;
int mid=(l+r)>>1;
for (int i=l;i<=mid;i++)
{
if (q[i].l<=q[i].r) add(q[i].l,q[i].k),add(q[i].r+1,-q[i].k);
else
{
add(q[i].l,q[i].k);add(m+1,-q[i].k);
add(1,q[i].k); add(q[i].r+1,-q[i].k);
}
}
if (l==r)
{
for (int x=a;x<=b;x++)
{
LL t=0;
for (int i=point[st[x].id];i;i=nxt[i])
{
t+=qurry(v[i]);
if (t>=st[x].hop) {ans[st[x].id]=l;break;}
}
if (t<st[x].hop) ans[st[x].id]=-1;
}
for (int i=l;i<=mid;i++)
{
if (q[i].l<=q[i].r) add(q[i].l,-q[i].k),add(q[i].r+1,q[i].k);
else
{
add(q[i].l,-q[i].k);add(m+1,q[i].k);
add(1,-q[i].k); add(q[i].r+1,q[i].k);
}
}
return;
}
int pa=0,pb=b-a+1;
for (int x=a;x<=b;x++)
{
LL t=0;
for (int i=point[st[x].id];i;i=nxt[i])
{
t+=qurry(v[i]);
if (t>=st[x].hop) {st[x].num=++pa;break;}
}
if (t<st[x].hop) st[x].num=++pb,st[x].hop-=t;
}
for (int i=l;i<=mid;i++)
{
if (q[i].l<=q[i].r) add(q[i].l,-q[i].k),add(q[i].r+1,q[i].k);
else
{
add(q[i].l,-q[i].k);add(m+1,q[i].k);
add(1,-q[i].k); add(q[i].r+1,q[i].k);
}
}
sort(st+a,st+b+1,cmp1);
ef(l,mid,a,a+pa-1);
ef(mid+1,r,a+pa,b);
}
int cmp(hh a,hh b){return a.id<b.id;}
int main()
{
scanf("%d%d",&n,&m);int x,k;
for (int i=1;i<=m;i++) scanf("%d",&x),addline(x,i);
for (int i=1;i<=n;i++) scanf("%lld",&st[i].hop),st[i].id=i;
scanf("%d",&k);
for (int i=1;i<=k;i++) scanf("%d%d%lld",&q[i].l,&q[i].r,&q[i].k);
ef(1,k,1,n);
sort(st+1,st+n+1,cmp);
for (int i=1;i<=n;i++)
if (ans[i]==-1) printf("NIE\n");else printf("%lld\n",ans[i]);
}