当前位置:   article > 正文

Codeforces Round #768 (div1)(A~D)_codeforces round 768 (div. 1)

codeforces round 768 (div. 1)

这场因为明早有事就没更新,赛中过了A~C,D来不及写了,赛后5分钟码好提交2wa。。

A. And Matching(思维+分类讨论)

开局想到的就是优先将 i~n-i-1 匹配,答案为0,之后以一次交换得出贡献值,喜提一发wa,之后想了20多分钟才发现还有特判情况。。

首先对于k!=n-1时候,我们将之前的匹配进行一次换位,即n-1~k,0~n-k-1,其余不变即可

而对于k=n-1&&n>4的情况,我们发现将1与2两点交换可以得出3的贡献,因此变为n-3与0的交换

而k=n-1&&n=4的情况输出-1即可

  1. #include <bits/stdc++.h>
  2. #define ll long long
  3. #define ls p<<1
  4. #define rs p<<1|1
  5. #define Ma 2<<20
  6. #define mod 1000000007
  7. using namespace std;
  8. struct node
  9. {
  10. ll l,r;
  11. }t[Ma];
  12. int main()
  13. {
  14. ll tt;
  15. scanf("%lld",&tt);
  16. while (tt--)
  17. {
  18. ll n,k;
  19. scanf("%lld%lld",&n,&k);
  20. for (ll i=0;i<n/2;i++)
  21. t[i].l=i,t[i].r=n-i-1;
  22. if (n==k+1&&n==4)
  23. printf("-1\n");
  24. else if (n==k+1)
  25. {
  26. swap(t[1].l,t[2].l);
  27. swap(t[3].l,t[0].r);
  28. ll ans=0;
  29. for (ll i=0;i<n/2;i++)
  30. printf("%lld %lld\n",t[i].l,t[i].r),ans+=t[i].l&t[i].r;
  31. }
  32. else
  33. {
  34. if (k<n/2)
  35. swap(t[0].r,t[k].r);
  36. else
  37. swap(t[0].r,t[n-k-1].l);
  38. for (ll i=0;i<n/2;i++)
  39. printf("%lld %lld\n",t[i].l,t[i].r);
  40. }
  41. }
  42. return 0;
  43. }

B. Range and Partition(摸你+贪心

我们发现对于[l,r]中的元素>=在[l,r]的元素+k,便一定能满足答案,因此我们可以得出在[l,r]中的元素至少有(n+k+1)/2个,因此将元素排序后贪心得出最优的[l,r],并进行分配即可。

  1. #include <bits/stdc++.h>
  2. #define ll long long
  3. #define ls p<<1
  4. #define rs p<<1|1
  5. #define Ma 1000005
  6. #define mod 1000000007
  7. using namespace std;
  8. ll a[Ma],b[Ma];
  9. int main()
  10. {
  11. ll tt;
  12. scanf("%lld",&tt);
  13. while (tt--)
  14. {
  15. ll n,m;
  16. scanf("%lld%lld",&n,&m);
  17. for (ll i=1;i<=n;i++)
  18. scanf("%lld",&a[i]),b[i]=a[i];
  19. sort(a+1,a+n+1);
  20. ll le=0,re=mod,add=(n+m+1)/2;
  21. for (ll i=1;i+add-1<=n;i++)
  22. if (a[i+add-1]-a[i]<re-le)
  23. le=a[i],re=a[i+add-1];
  24. printf("%lld %Lld\n",le,re);
  25. ll pre=1,w=0,cnt=1;
  26. for (ll i=1;i<=n&&cnt<m;i++)
  27. {
  28. if (b[i]>=le&&b[i]<=re)
  29. w++;
  30. else
  31. w--;
  32. if (w>=1)
  33. {
  34. cnt++;
  35. printf("%lld %lld\n",pre,i);
  36. pre=i+1,w=0;
  37. }
  38. }
  39. printf("%lld %lld\n",pre,n);
  40. //printf("\n");
  41. }
  42. return 0;
  43. }

C. Paint the Middle(贪心+dp+区间优化)

假设有这样的一串1......1.....1....1,最优取法一定是头与尾,因此我们可以认为[l,r](a[l]==a[r])

的区间进行筛选,对于r来说无关紧要,因此我们所使用的区间为[l,r-1],贡献为r-l-1。

假设有这样的k个区间,我们可以n~1的进行他的头优化

最后进行dp维护即可。

  1. #include <bits/stdc++.h>
  2. #define ll long long
  3. #define ls p<<1
  4. #define rs p<<1|1
  5. #define Ma 1000005
  6. #define mod 1000000007
  7. using namespace std;
  8. ll dp[Ma];
  9. ll pre[Ma];
  10. vector <ll> a[Ma];
  11. ll tot=0;
  12. int main()
  13. {
  14. ll n;
  15. scanf("%lld",&n);
  16. for (ll i=1;i<=n;i++)
  17. pre[i]=i;
  18. for (ll i=1;i<=n;i++)
  19. {
  20. ll x;
  21. scanf("%lld",&x);
  22. a[x].push_back(i);
  23. }
  24. for (ll i=1;i<=n;i++)
  25. if (a[i].size()>=2)
  26. pre[a[i][a[i].size()-1]-1]=a[i][0];
  27. ll l=n;
  28. for (ll i=n;i>=1;i--)
  29. {
  30. l=min(l,pre[i]);
  31. pre[i]=l;
  32. }
  33. for (ll i=1;i<=n;i++)
  34. dp[i]=max(dp[i-1],dp[pre[i]-1]+i-pre[i]);
  35. printf("%lld\n",dp[n]);
  36. return 0;
  37. }

D. Flipping Range(分类+数学)

首先我们要得到一个操作,我们先假设操作长度为k,那么我们得到两个操作。

1.进行[l,l+k-1]操作,得到的效果为[l,l+k-1]变号

2.进行[l,l+k-1]操作与[l+1,l+k]操作,得到的效果为l与l+k变号

通过这一步我们可以发现对于i%k的点中会有奇数/偶数个变号,因此我们可以分类得出答案。

下面就是如何找到这个k了。对于b的区间长度操作,我们可以发现我们可以得出的最小区间操作为

gcd(b),因此这道题便解决了(doge)。

  1. #include <bits/stdc++.h>
  2. #define ll long long
  3. #define ls p<<1
  4. #define rs p<<1|1
  5. #define Ma 1000005
  6. #define mod 1000000007
  7. using namespace std;
  8. ll n,k,m;
  9. vector <ll> a[Ma];
  10. ll tot[Ma];
  11. ll d[Ma],b[Ma];
  12. ll sol(ll x)
  13. {
  14. ll ans=0;
  15. for (ll i=0;i<m;i++)
  16. {
  17. ll j=0;
  18. if (x==1)
  19. ans+=-a[i][j],j++;
  20. for (;j+1<a[i].size();j+=2)
  21. ans+=abs(a[i][j]+a[i][j+1]);
  22. for (;j<a[i].size();j++)
  23. ans+=a[i][j];
  24. }
  25. return ans;
  26. }
  27. int main()
  28. {
  29. ll tt;
  30. scanf("%lld",&tt);
  31. while (tt--)
  32. {
  33. m=0;
  34. scanf("%lld%lld",&n,&k);
  35. for (ll i=0;i<n;i++)
  36. scanf("%lld",&d[i]);
  37. for (ll i=0;i<k;i++)
  38. {
  39. ll x;
  40. scanf("%lld",&x);
  41. m=__gcd(x,m);
  42. }
  43. for (ll i=0;i<m;i++)
  44. a[i].clear(),tot[i]=0;
  45. for (ll i=0;i<n;i++)
  46. a[i%m].push_back(d[i]);
  47. for (ll i=0;i<m;i++)
  48. sort(a[i].begin(),a[i].end());
  49. printf("%lld\n",max(sol(0),sol(1)));
  50. }
  51. return 0;
  52. }

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小蓝xlanll/article/detail/519189
推荐阅读
相关标签
  

闽ICP备14008679号