线段树肯定会 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 "); else printf("%d ",result[i]); return 0; }