【SPOJ METEORS】 Meteors
http://www.spoj.com/problems/METEORS/ (题目链接)
题意
一个星球上有$m$个空间站排列在一个环形轨道上,每个空间站仅属于一个国家。总共有$K$场流星雨,这些流星雨降落在区间$[l,r]$的空间站并带来$w$的陨石。每个国家想要收获$p_i$的陨石,问每个国家最少在第几场流星雨过后收集到的陨石达到要求。
Solution
整体二分很明显,一开始复杂度算错了T_T。
细节
本机7s,SPOJ竟然跑过去了w(゚Д゚)w。听说会爆LL
代码
// spojMETEORS #include<algorithm> #include<iostream> #include<cstdlib> #include<cstring> #include<cstdio> #include<cmath> #define LL long long #define ULL unsigned long long #define inf 2147483600 #define Pi acos(-1.0) #define free(a) freopen(a".in","r",stdin),freopen(a".out","w",stdout) using namespace std; inline int gi() { int x=0,f=1;char ch=getchar(); while (ch<'0' || ch>'9') {if (ch=='-') f=-1;ch=getchar();} while (ch>='0' && ch<='9') {x=x*10+ch-'0';ch=getchar();} return x*f; } const int maxn=300010; int n,m,K,cnt,a[maxn],ans[maxn],head[maxn]; struct edge {int to,next;}e[maxn]; struct data {int w,id;}p[maxn],lp[maxn],rp[maxn]; struct node {int l,r;ULL s,tag;}tr[maxn<<2]; struct mete {int l,r,w;}q[maxn]; namespace Segtree { void build(int k,int s,int t) { tr[k].l=s;tr[k].r=t; if (s==t) return; int mid=(s+t)>>1; build(k<<1,s,mid); build(k<<1|1,mid+1,t); } void modify(int k,int s,int t,LL val) { int l=tr[k].l,r=tr[k].r,mid=(l+r)>>1; if (l==s && r==t) {tr[k].s+=val*(r-l+1);tr[k].tag+=val;return;} if (t<=mid) modify(k<<1,s,t,val); else if (s>mid) modify(k<<1|1,s,t,val); else modify(k<<1,s,mid,val),modify(k<<1|1,mid+1,t,val); tr[k].s=tr[k<<1].s+tr[k<<1|1].s; } ULL query(int k,int p) { int l=tr[k].l,r=tr[k].r,mid=(l+r)>>1; if (l==r) return tr[k].s; if (p<=mid) return query(k<<1,p)+tr[k].tag; else return query(k<<1|1,p)+tr[k].tag; } } using namespace Segtree; void link(int u,int v) { e[++cnt]=(edge){v,head[u]};head[u]=cnt; } void solve(int ql,int qr,int l,int r) { if (ql>qr) return; int mid=(ql+qr)>>1,l1=0,l2=0; for (int i=ql;i<=mid;i++) { if (q[i].l>q[i].r) modify(1,q[i].l,m,q[i].w),modify(1,1,q[i].r,q[i].w); else modify(1,q[i].l,q[i].r,q[i].w); } for (int i=l;i<=r;i++) { ULL sum=0; for (int j=head[p[i].id];j;j=e[j].next) sum+=query(1,e[j].to); if (p[i].w<=sum) lp[++l1]=p[i],ans[p[i].id]=mid; else rp[++l2]=p[i]; } for (int i=1;i<=l1;i++) p[l+i-1]=lp[i]; for (int i=1;i<=l2;i++) p[r-i+1]=rp[i]; if (l+l1<=r) solve(mid+1,qr,l+l1,r); for (int i=ql;i<=mid;i++) { if (q[i].l>q[i].r) modify(1,q[i].l,m,-q[i].w),modify(1,1,q[i].r,-q[i].w); else modify(1,q[i].l,q[i].r,-q[i].w); } if (l<=r-l2) solve(ql,mid-1,l,r-l2); } int main() { n=gi(),m=gi(); for (int i=1;i<=m;i++) a[i]=gi(); for (int i=1;i<=m;i++) link(a[i],i); for (int i=1;i<=n;i++) p[i].w=gi(),p[i].id=i; K=gi(); for (int i=1;i<=K;i++) q[i].l=gi(),q[i].r=gi(),q[i].w=gi(); build(1,1,m); solve(1,K,1,n); for (int i=1;i<=n;i++) { if (!ans[i]) puts("NIE"); else printf("%d\n",ans[i]); } return 0; }
This passage is made by MashiroSky.