• D. Prefix Purchase CodeTON Round 6 (Div. 1 + Div. 2, Rated, Prizes!)


    Problem - D - Codeforces

    题目大意:有一个全为0的数组a,有一个费用数组c,给出总的可用费用k,每次操作可以花费c[i]使a[1]~a[i]中所有数+1,要求使a的字典序最大,输出满足条件的a

    1<=n<=2e5;1<=c[i]<=1e9

    思路:因为要a的字典序最大,所以初始状态下我们要找一个ma=k/c[i]最大,且i最大的位置mai,1~mai中的所有数都应该等于ma,显然,在这个区间内选择其他任意方案字典序都不如这样大。

    接下来考虑剩下来的mai+1~n的区间,我们可能在这里面选择一些数,替换掉之前的mai位置的数,即如果a[mai]*(ma-x)+x*a[i]<=k,那么我们就可将x个a[mai]换成x个a[i],这样1~mai中的数不变,mai+1~i的数都等于x。移项化简得x=(k-ma*a[mai])/(a[i]-a[mai]),即x=(k%a[mai])/(a[i]-a[mai]),这样1~i都处理好了,k=k%a[mai]%a[i],继续依照此法循环处理剩余的区间,每次区间+ma都用差分数组维护,直到k=0,后面的数肯定都是0了,退出循环。

    那么这样做会不会超时呢?首先考虑我们最终构造出的a数组中最多有多少不同数字,因为这些事都是k%一个数得出来的,对一个数取模最坏的情况就是对这个数/2+1取模,也就是最多进行log2(1e9)次取模,a中的数也就不超过30个,我们每次得出这个数都是O(n)的时间复杂度,最终的时间复杂度就是O(log(a[i])*n),在可接受范围内。

    1. //#include<__msvc_all_public_headers.hpp>
    2. #include
    3. using namespace std;
    4. typedef long long ll;
    5. const int N = 2e5 + 5;
    6. ll n;
    7. ll a[N];
    8. int l[N], r[N];
    9. bool vis[N];
    10. int k;
    11. int sum[N];
    12. void init()
    13. {
    14. for (int i = 1; i <= n+1; i++)
    15. {//初始化差分数组
    16. sum[i] = 0;
    17. }
    18. }
    19. void solve()
    20. {
    21. cin >> n;
    22. init();
    23. for (int i = 1; i <= n; i++)
    24. {
    25. cin >> a[i];
    26. }
    27. cin >> k;
    28. int ma = 0, mai = 0;//当前区间k/c[i]的最大值,最大值下标
    29. int pre = 0;//上一个区间内的最大值
    30. int now = 1;//待处理的区间的左端点
    31. while(1)
    32. {
    33. for (int i = now; i <= n; i++)
    34. {//遍历整个数组,得到k/c[i]的最大值
    35. if (k / (a[i]-pre) >= ma)
    36. {
    37. ma = k / (a[i]-pre);
    38. mai = i;
    39. }
    40. }
    41. sum[now] += ma;//差分数组区间+
    42. sum[mai + 1] -= ma;
    43. if (!ma)//最大值为0后面就都是0了
    44. break;
    45. k%=a[mai] - pre;//维护新的k
    46. if (!k)//k变成0后面就都是0了
    47. break;
    48. now = mai + 1;//维护待处理的区间的左端点
    49. if (now > n)
    50. break;
    51. pre = a[mai];
    52. ma = 0;
    53. }
    54. for (int i = 1; i <= n; i++)
    55. {
    56. sum[i] = sum[i - 1] + sum[i];
    57. cout << sum[i] << " ";
    58. }
    59. cout << endl;
    60. }
    61. int main()
    62. {
    63. ios::sync_with_stdio(false);
    64. cin.tie(0);
    65. int t;
    66. cin>>t;
    67. while (t--)
    68. {
    69. solve();
    70. }
    71. return 0;
    72. }
    73.  

  • 相关阅读:
    Pytorch导出onnx模型,C++转化为TensorRT并实现推理过程
    ResNet网络的搭建
    js+html实现打字游戏v2
    数字孪生3D可视化,人员定位系统助力企业数字化转型
    Vue实现Hello World
    003-Java程序流程控制
    SMARTPHONE PLATFORM st解决方案
    JavaWeb | 七个步骤,完成一个servlet的hello world程序
    移动平台助力推进智慧型科研院所信息化建设
    Springboot 集成 RocketMQ(进阶-消息)
  • 原文地址:https://blog.csdn.net/ashbringer233/article/details/133020702