题目描述:
这个星球经常会下陨石雨。BIU已经预测了接下来K场陨石雨的情况。 BIU的第i个成员国希望能够收集Pi单位的陨石样本。你的任务是判断对于每个国家,它需要在第几次陨石雨之后,才能收集足够的陨石。 输入: 第一行是两个数N,M。 第二行有M个数,第i个数Oi表示第i段轨道上有第Oi个国家的太空站。 第三行有N个数,第i个数Pi表示第i个国家希望收集的陨石数量。 第四行有一个数K,表示BIU预测了接下来的K场陨石雨。 接下来K行,每行有三个数Li,Ri,Ai,表示第K场陨石雨的发生地点在从Li顺时针到Ri的区间中(如果Li<=Ri,就是Li,Li+1,...,Ri,否则就是Ri,Ri+1,...,m-1,m,1,...,Li),向区间中的每个太空站提供Ai单位的陨石样本。 输出: N行。第i行的数Wi表示第i个国家在第Wi波陨石雨之后能够收集到足够的陨石样本。如果到第K波结束后仍然收集不到,输出NIE。
数据范围: 1<=n,m,k<=3*10^5 1<=Pi<=10^9 1<=Ai<10^9
Sample Input
3 5
1 3 2 1 3
10 5 7
3
4 2 4
1 3 1
3 5 2
Sample Output
3
NIE
1
据说这道题可以用斐波那契数列+二分过,
但我菜到只会用整体二分,请求原谅QWQ......
上代码:
#include<cstdio>
#include<iostream>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<queue>
#define fo(i,j,k) for(int i=j;i<=k;i++)
#define int long long
using namespace std;
const int maxn=300005;
int c[maxn];
int ans[maxn];
int n,m,Q,x,now;
vector<int>to[maxn];
struct query{int l,r,val;}q[maxn];
struct node{int id,k;}a[maxn],tmp[maxn];
inline int lowbit(int x){return x&-x;}
inline void add(int u,int v)
{
for(int i=u;i<=m;i+=lowbit(i))
c[i]+=v;
}
inline int getsum(int u)
{
int sum=0;
for(int i=u;i>=1;i-=lowbit(i))
sum+=c[i];
return sum;
}
inline void Add(int l,int r,int v)
{
if(l<=r) add(l,v),add(r+1,-v);
else add(l,v),add(1,v),add(r+1,-v);
}
inline void CDQ(int L,int R,int l,int r)//别看他叫CDQ,那他也是整体二分。
{
int l1=L,l2=R,mid=(l+r>>1);
if(l==r)
{
fo(i,L,R) ans[a[i].id]=l;
return;
}
while(now<=mid) now++,Add(q[now].l,q[now].r,q[now].val);
while(now>mid) Add(q[now].l,q[now].r,-q[now].val),now--;
// fo(i,1,mid) Add(q[i].l,q[i].r,q[i].val);
fo(i,L,R)
{
int sum=0;
for(int j=0;j<to[a[i].id].size();j++)
{
int czy=to[a[i].id][j];
sum+=getsum(czy);
if(sum>=a[i].k) break;
}
if(sum>=a[i].k) tmp[l1++]=a[i];
else tmp[l2--]=a[i];
}
reverse(tmp+l2+1,tmp+R+1);
fo(i,L,R) a[i]=tmp[i];
// fo(i,1,mid) Add(q[i].l,q[i].r,-q[i].val);
CDQ(L,l1-1,l,mid);
CDQ(l2+1,R,mid+1,r);
}
signed main()
{
scanf("%lld%lld",&n,&m);
fo(i,1,m)
{
scanf("%lld",&x);
to[x].push_back(i);
}
fo(i,1,n) a[i].id=i,scanf("%lld",&a[i].k);scanf("%lld",&Q);
fo(i,1,Q) scanf("%lld%lld%lld",&q[i].l,&q[i].r,&q[i].val);
Q++,q[Q].l=1,q[Q].r=m,q[Q].val=1e9+7;
CDQ(1,n,1,Q);
fo(i,1,n)
if(ans[i]<Q) printf("%lld\n",ans[i]);
else puts("NIE");
return 0;
}
解决一个涉及陨石雨收集的问题,使用整体二分法优化算法效率。通过预处理和区间更新,快速确定各国何时能收集到足够陨石。
2146





