CodeForces 536A Tavas and Karafs :n个数每次最多将m个数-1,快速计算减完次数:二分/贪心

英语弱是硬伤啊==比赛看了A半小时活生生没看懂题意,后来带数据带猜才明白题意

输入A,B,n,表示一个首项为A公差为B的数,n个询问

每个询问给出l,t,m你需要算出最大的r,使l-r之间的数通过(标题上面)的规则在t次内减完==

看明白题意,首先想到就是一个二分,然后在二分中需要快速check出是否可行,比赛想到了一个错误的贪心方案,然后一直调到比赛结束草草草===

不冷静,蠢==

其实贪心策略不能按照m个分组那样,其实应该对于n个数,每次应该动态的取出最大的m个-1,这样算出来就是最少次数

但是肯定不能用优先队列取模拟,可以找到规律其实是max(a[r],sum(a[l]-a[r])/m->向上取整) thinking

 1 #include<stdio.h>
 2 #include<string.h>
 3 #include<algorithm>
 4 using namespace std;
 5 #define  LL long long
 6 LL a[2000005],s[2000005]={0};
 7 int main()
 8 {
 9   LL n,i,t,l,m,ql,qr,mid,A,B;
10   scanf("%I64d%I64d%I64d",&A,&B,&n);
11   a[1]=s[1]=A;
12   for (i=2;i<=2000000;i++) {
13     a[i]=a[i-1]+B;
14     s[i]=s[i-1]+a[i];
15   }
16   while (n--){
17     scanf("%I64d%I64d%I64d",&l,&t,&m);
18     ql=l; qr=2000000;
19     if (a[ql]>t) {printf("-1\n"); continue; }
20     while (ql+1<qr){
21       mid=(qr+ql)/2;
22           LL tmp=max(a[mid],(s[mid]-s[l-1])%m==0?(s[mid]-s[l-1])/m:((s[mid]-s[l-1])/m+1));
23       if (tmp<=t) ql=mid;
24       else qr=mid;
25     }
26     printf("%I64d\n",ql);
27   }
28   return 0;
29 }
View Code

题目链接:http://codeforces.com/contest/536/problem/A

posted on 2015-04-15 17:49  xiao_xin  阅读(422)  评论(0编辑  收藏  举报

导航