音乐节拍【模拟】
题目大意:
思路:
几万的范围,肯定过不了,但可以过。
我们可以使用离线做法,将问题排序,再用指针指向每一个问题,由于这时问题满足单调递增,所以总共就只要,平均每次循环,再加上枚举的大循环,求出答案就只要所以这样做总时间复杂度为。
当然这道题还可以用二分,时间复杂度。
代码:
#include <cstdio>
#include <iostream>
#include <algorithm>
using namespace std;
int n,m,a[80001],j;
struct N
{
int num,q,ans;
}b[80001];
bool cmp(N x,N y)
{
return x.q<y.q;
}
bool cmp2(N x,N y)
{
return x.num<y.num;
}
int main()
{
freopen("mnotes.in","r",stdin);
freopen("mnotes.out","w",stdout);
scanf("%d%d",&n,&m);
for (int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
a[i]+=a[i-1]; //前缀和
}
for (int i=1;i<=m;i++)
{
scanf("%d",&b[i].q);
b[i].num=i;
}
sort(b+1,b+m+1,cmp); //排序
j=1; //指针
for (int i=1;i<=n;i++)
{
while (b[j].q<a[i]) //单调性
{
b[j].ans=i;
j++;
if (j>m) break;
}
if (j>m) break;
}
sort(b+1,b+m+1,cmp2); //排回去
for (int i=1;i<=m;i++)
printf("%d\n",b[i].ans);
return 0;
}