二分一个答案,对
≤
这个答案的国家
分到左边一组,其余的分到右面一组继续向下分治递归处理
ps:
迷之
WA
可能是过程中爆了
longlong
!!
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cstdio>
#include<vector>
#include<queue>
#include<cmath>
#include<set>
#include<map>
#define lowbit(x) (x&(-x))
#define N 310000
#define ll long long
using namespace std;
int sc()
{
int i=0,f=1;char c=getchar();
while(c>'9'||c<'0'){if(c=='-')f=-1;c=getchar();}
while(c>='0'&&c<='9')i=i*10+c-'0',c=getchar();
return i*f;
}
struct W{int l,r,v;}a[N];
int head[N],nxt[N],lst[N],nd[N];
int q[N],q1[N],q2[N],ans[N],now;
ll tr[N],sum[N];
int n,m,tot,K;
void insert(int x,int y)
{
lst[++tot]=y;nxt[tot]=head[x];head[x]=tot;
}
void change(int x,int f)
{
for(;x<=m;x+=lowbit(x))
tr[x]+=f;
}
void updata(int x,int f)
{
if(a[x].r>=a[x].l)
{
change(a[x].l,f*a[x].v);
change(a[x].r+1,-f*a[x].v);
}
else
{
change(a[x].l,f*a[x].v);
change(a[x].r+1,-f*a[x].v);
change(1,f*a[x].v);
}
}
ll ask(int x)
{
ll ans=0;
for(;x;x-=lowbit(x))
ans+=tr[x];
return ans;
}
void solve(int s,int t,int l,int r)
{
if(t<s)return;
if(l==r)
{
for(int i=s;i<=t;i++)
ans[q[i]]=l;
return;
}
int mid=l+r>>1;
while(now<mid)updata(++now,1);
while(now>mid)updata(now--,-1);
int p1=0,p2=0;
for(int i=s;i<=t;i++)
{
ll sum=0;
for(int j=head[q[i]];j;j=nxt[j])
{
sum+=ask(lst[j]);
if(sum>=nd[q[i]])break;//sum答案会爆long long!!!!!!!!!!!!!!!!!!!!
}
if(sum>=nd[q[i]])
q1[++p1]=q[i];
else
q2[++p2]=q[i];
}
for(int i=1;i<=p1;i++) q[s+i-1]=q1[i];
for(int i=1;i<=p2;i++) q[s+p1+i-1]=q2[i];
solve(s,s+p1-1,l,mid),solve(s+p1,t,mid+1,r);
}
int main()
{
n=sc(),m=sc();
for(int i=1;i<=m;i++)
insert(sc(),i);
for(int i=1;i<=n;i++)
nd[q[i]=i]=sc();
K=sc();
for(int i=1;i<=K;i++)
a[i].l=sc(),a[i].r=sc(),a[i].v=sc();
solve(1,n,1,K+1);
for(int i=1;i<=n;i++)
if(ans[i]<=K)
printf("%d\n",ans[i]);
else puts("NIE");
return 0;
}