线段树肯定会 TLE 的,必须要用树状数组.
Code:
// luogu-judger-enable-o2
#include <cstdio>
#include <algorithm>
#include <vector>
#include <cstring>
#include <cctype>
#define setIO(s) freopen(s".in","r",stdin)
#define maxn 300009
#define ll long long
using namespace std;
vector<int>G[maxn];
int n,m,k,cnt[maxn],left[maxn<<1],right[maxn<<1],que[maxn],result[maxn];
int tl[maxn],tr[maxn];
int current[maxn],cost[maxn],w[maxn<<1];
inline int read()
{
int k=0,f=1;char c=getchar();
for(;!isdigit(c);c=getchar()) if(c=='-')f=-1;
for(;isdigit(c);c=getchar()) k=k*10+c-'0';return f*k;
}
struct Segment_Tree{
ll sumv[maxn<<2],lazy[maxn<<2];
#define lson (o<<1)
#define rson (o<<1)|1
void mark(int l,int r,int o,int delta)
{
sumv[o]+=delta*(r-l+1);
lazy[o]+=delta;
}
int lowbit(int x){ return x&(-x); }
void update(int l,int r,int L,int R,int o,int k){
while(L<=r) sumv[L]+=k,L+=lowbit(L);
++R;
while(R<=r) sumv[R]-=k,R+=lowbit(R);
}
ll query(int l,int r,int pos,int pos2,int o){
ll sum=0;
while(pos>0) sum+=sumv[pos],pos-=lowbit(pos);
return sum;
}
}tree;
void solve(int x,int y,int l,int r){
if(x>y||l>r) return;
if(l==r){
for(int i=x;i<=y;++i) result[que[i]]=l;
return;
}
int mid=(l+r)>>1,p=0,q=0,qcnt;
ll s;
for(int i=l;i<=mid;++i) {
for(int cur=cnt[i-1]+1;cur<=cnt[i];++cur) {
tree.update(1,m,left[cur],right[cur],1,w[cur]);
}
}
for(int i=x;i<=y;++i){
int u=que[i];
int siz=G[u].size();
s=current[u];
for(int j=0;j<siz&&s<=(ll)cost[u];++j)
s+=tree.query(1,m,G[u][j],G[u][j],1);
if(s>=cost[u]) tl[++p]=u;
else tr[++q]=u,current[u]=s;
}
for(int i=l;i<=mid;++i)
for(int cur=cnt[i-1]+1;cur<=cnt[i];++cur)
tree.update(1,m,left[cur],right[cur],1,-w[cur]);
qcnt=x-1;
for(int i=1;i<=p;++i) que[++qcnt]=tl[i];
for(int i=1;i<=q;++i) que[++qcnt]=tr[i];
solve(x,x+p-1,l,mid),solve(x+p,y,mid+1,r);
}
int main(){
//setIO("input");
n=read(),m=read();
for(int i=1;i<=m;++i)
{
int a=read();
G[a].push_back(i);
}
for(int i=1;i<=n;++i) cost[i]=read();
k=read();
int idx=0;
for(int i=1;i<=k;++i){
int l,r,c;
l=read(),r=read(),c=read();
if(l<=r) cnt[i]=++idx,left[idx]=l,right[idx]=r,w[idx]=c;
else {
cnt[i]=++idx;
left[idx]=l,right[idx]=m,w[idx]=c;
cnt[i]=++idx;
left[idx]=1,right[idx]=r,w[idx]=c;
}
}
for(int i=1;i<=n;++i) que[i]=i;
cnt[++k]=++idx;
left[idx]=1,right[idx]=m,w[idx]=(int)1e9;
solve(1,n,1,k);
for(int i=1;i<=n;++i)
if(result[i]==k) printf("NIE\n");
else printf("%d\n",result[i]);
return 0;
}