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 }