整体二分:二分操作。
首先,memset很慢。
其次,最好开long long。
然后,最后再下一场inf流星雨保证能够出解。
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #define maxn 300500 #define inf 1000000010 using namespace std; long long n,m,k,o[maxn],p[maxn],id[maxn],nxt[maxn],g[maxn],val[maxn],ans[maxn]; long long cur[maxn],tmp[maxn]; long long x,y,z,tol[maxn],tor[maxn]; struct meteor { long long l,r,a; }q[maxn]; void addcon(long long con,long long now) { nxt[now]=g[con]; g[con]=now; } void addmet(long long left,long long right,long long a,long long now) { q[now].l=left; q[now].r=right; q[now].a=a; } long long lowbit(long long x) { return ((-x)&x); } void modify(long long now,long long x) { for (long long i=now;i<=m;i+=lowbit(i)) val[i]+=x; } void modifys(long long now,long long x) { if (q[now].l<=q[now].r) { modify(q[now].l,x); if (q[now].r+1<=m) modify(q[now].r+1,-x); } else { modify(q[now].l,x); modify(1,x); modify(q[now].r+1,-x); } } long long query(long long x) { long long ret=0; for (long long i=x;i>=1;i-=lowbit(i)) ret+=val[i]; return ret; } void half_solve(long long head,long long tail,long long left,long long right) { if (head>tail) return; long long lsum=0,rsum=0; if (left==right) { for (long long i=head;i<=tail;i++) ans[id[i]]=left; return; } long long mid=(left+right)>>1; for (long long i=left;i<=mid;i++) modifys(i,q[i].a); for (long long i=head;i<=tail;i++) { tmp[id[i]]=0; for (long long j=g[id[i]];j;j=nxt[j]) { tmp[id[i]]+=query(j); if (cur[id[i]]+tmp[id[i]]>p[id[i]]) break; } if (cur[id[i]]+tmp[id[i]]>=p[id[i]]) tol[++lsum]=id[i]; else {cur[id[i]]+=tmp[id[i]];tor[++rsum]=id[i];} } for (long long i=left;i<=mid;i++) modifys(i,-q[i].a); for (long long i=1;i<=lsum;i++) id[head-1+i]=tol[i]; for (long long i=1;i<=rsum;i++) id[head-1+lsum+i]=tor[i]; half_solve(head,head+lsum-1,left,mid); half_solve(head+lsum,tail,mid+1,right); } int main() { scanf("%lld%lld",&n,&m); for (long long i=1;i<=m;i++) { scanf("%lld",&o[i]); addcon(o[i],i); } for (long long i=1;i<=n;i++) { scanf("%lld",&p[i]); id[i]=i; } scanf("%lld",&k); for (long long i=1;i<=k;i++) { scanf("%lld%lld%lld",&x,&y,&z); addmet(x,y,z,i); } k++;addmet(1,n,inf,k); half_solve(1,n,1,k); for (long long i=1;i<=n;i++) { if (ans[i]==k) printf("NIE\n"); else printf("%lld\n",ans[i]); } return 0; }