B  我也不是B

  这个题做了一下午,比赛两个小时还是没做出来,比完赛才知道要用一个倍增算法确定区间,然后再二分右端点。

  题意:定义一个序列的混乱度为累加和:b[i]*v[i],b[i]为这个序列中第i小的数,v[]数组是给定的。如果当前加进来的数购车的数构成的序列的混乱度大于m,则将当前的序列扔掉,然后将变量C加一,现在给出要加进来的序列的顺序,和v[]数组,求最终C的值。

思路:枚举左端点,二分右端点,暴力判断混乱度与M的关系,如果Me为0,只能一个一个删除,那么二分貌似会将复杂度拉高,所以为了避免这种情况我们要用倍增算法确定二分区间,假设当前左端点为i,于是枚举一个k使得[i,i+2^k]刚好大于M,于是,我们要改变C的位置必定在[i+2^(k-1),i+2^k]内,然后对这个区间二分暴力判断。

好吧,本弱只想到了枚举左端点二分右端点,未曾想到用倍增法进一步确定区间减少二分次数。也算学到了。

const int N=1e6+10;
int n;
ll m,a[N],v[N],b[N],num[N];
bool find(int l,int r)
{
int len=0;
ll sum=0;
for(int i=l; i<=r; i++) b[len++]=a[i];
sort(b,b+len);
for(int i=0; i<len; i++)
{
sum+=b[i]*v[i];
if(sum>m) return true;
}
return false;
}
int main()
{
while(~scanf("%d%lld",&n,&m))
{
for(int i=0; i<n; i++) scanf("%lld",&a[i]);
for(int i=0; i<n; i++) scanf("%lld",&v[i]);
int c=0,j=0;
for(int i=0; i<n; i++) //枚举左端点,二分右端点
{
int k,ans=0,l=i+1,r=n-1;
for(k=1; k<n; k*=2) if(find(i,i+k)) break;
l=i+k/2,r=i+k;
while(l<r)
{
int mid=(l+r)/2;
if(find(i,mid)) r=mid;
else l=mid+1;
}
for(i; i<=l; i++)
{
if(i==l)
{
num[i]=++c;
break;
}
num[i]=c;
}
}
for(int i=0; i<n; i++)
{
printf("%d",num[i]);
if(i!=n-1) printf(" ");
else printf("\n");
}
}
return 0;
}

最新文章

  1. 学习zepto.js(对象方法)[5]
  2. UVA 11552 四 Fewest Flops
  3. 根据IP定位获取城市代码
  4. 国内银行CNAPS CODE 查询
  5. JavaScript jQuery 事件、动画、扩展
  6. php_中替换换行符
  7. 基于Jcrop的图片上传裁剪加预览
  8. Node.js安装和配置
  9. Android 自定义 permission
  10. 关于第一次STM32连接电脑下载程序
  11. ajax跨域请求问题及解决办法总结
  12. CentOS6.5yum配置本地源
  13. ios之animateWithDuration的坑
  14. 第36章:MongoDB-集群--Replica Sets(副本集)
  15. 012.Docker私有仓库多Harbor同步部署
  16. P1552 [APIO2012]派遣
  17. java 偏向锁,轻量锁,重量级锁
  18. 团队作业——Beta冲刺5
  19. 号称简明实用的django上手教程
  20. 2018.09.15 poj2117Electricity(割点)

热门文章

  1. main函数与命令行参数
  2. Vue的十个常用指令
  3. 洛谷 P2872 [USACO07DEC]道路建设Building Roads
  4. SQL增删查改语句
  5. js 双向绑定
  6. 自学Spring Boot
  7. Servlet Context
  8. 补题—Codeforces Round #346 (Div. 2) _智商欠费系列
  9. 复合词UVa10391(STL简单应用)
  10. 6.python