Codeforces Round #757 (Div. 2)ABCD1

Posted 小哈里

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Codeforces Round #757 (Div. 2)ABCD1相关的知识,希望对你有一定的参考价值。

A

题意:

  • n个物品各有一个价格,不买小于l和大于r的,有k块钱,最多可以买几件?

思路:

  • 去掉不买的从小到大排个序,买到不能买为止。
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int maxn = 1e5+10;
int main()
    ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
    int T;  cin>>T;
    while(T--)
        int n, l, r, k;  cin>>n>>l>>r>>k;
        vector<int>vc;
        for(int i = 1; i <= n; i++)
            int x;  cin>>x;
            if(x>=l && x<=r)vc.push_back(x);
        
        sort(vc.begin(),vc.end());
        int ans = 0;
        for(int x: vc)
            //cout<<x<<"\\n";
            if(k >= x)
                ans++;  k -= x;
            else
                break;
            
        
        cout<<ans<<"\\n";
    
    return 0;


B

题意:

  • 数轴上需要摆放一共n+1个点,两点距离为差的绝对值。
  • 从0号点出发到其他n个点分别来回走ai次,求总距离最小的点摆放方案。

思路:

  • 0号点放在0,剩下的点按照需要走的次数从大到小排序,依次在0号点一左一右摆放上去即可。
  • 记得开longlong不然会WA4
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const LL maxn = 1e5+10;
int main()
    ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
    LL T;  cin>>T;
    while(T--)
        LL n;  cin>>n;
        vector<pair<LL,LL> >vc;
        for(LL i = 1; i <= n; i++)
            LL x;  cin>>x;
            vc.push_back(make_pair(x,i));
        
        sort(vc.begin(),vc.end());
        vector<LL>p(n+1);
        p[0] = 0;
        LL l = -1, r = 1, ans = 0;
        for(LL i = vc.size()-1; i >= 0; i--)
            if(i%2==0)
                p[vc[i].second] = l;
                ans += abs(0-l)*2*vc[i].first;
                l--;
            else
                p[vc[i].second] = r;
                ans += abs(r-0)*2*vc[i].first;
                r++;
            
        
        cout<<ans<<"\\n";
        for(LL i = 0; i <= n; i++)
            cout<<p[i]<<" ";
        
        cout<<"\\n";
    
    return 0;


C

题意:

  • 长为n的数组,给出m对l,r,x,表示a[l] 按位或 a[l+1] … 按位或a[r]的值为x。
  • 求原数组所有子序列按位异或和的总和。

思路:

  • 依次考虑每一位的贡献,如果存在该位为1,那么互相异或后,不管出现多少次,都会产生pows(2,i-1)的贡献。如果全or也是0,那么最后贡献肯定也是0。
  • 所以结论为pows(2,n-1)*所有x异或后的数。
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int maxn = 1e5+10;
const int mod = 1e9+7;
LL pows(LL a, LL x, LL p)if(x==0)return 1; LL t = pows(a, x>>1,p);if(x%2==0)return t*t%p;return t*t%p*a%p;
int main()
    ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
    int T;  cin>>T;
    while(T--)
        int n, m;  cin>>n>>m;
        int ans = 0;
        for(int i = 1; i <= m; i++)
            int l, r, x;  cin>>l>>r>>x;
            ans |= x;
        
        ans = ans*pows(2,n-1,mod)%mod;
        cout<<ans<<"\\n";
    
    return 0;



D1

题意:

  • 给出一个长为n的序列,求构造一种排序方式,让 ∑ i = 1 n g c d ( a 1 , a 2 , a 3 , , , a i ) \\sum_i=1^ngcd(a1,a2,a3,,,ai) i=1ngcd(a1,a2,a3,,,ai)的值最大,输出这个值。

思路:

  • 令s[i]表示a中第i个数的倍数有几个,dp[i]表示以第i个数开头的最大值。
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int maxn = 5e6+10;
LL s[maxn], dp[maxn];
int main()
    ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
    int n;  cin>>n;
    for(int i = 1; i <= n; i++)
        int x;  cin>>x;  s[x]++;
    
    for(int i = 1; i < maxn; i++)
        for(int j = 2*i; j < maxn; j+=i)
            s[i] += s[j];
        
    
    LL ans = 0;
    for(int i = maxn-5; i >= 1; i--)
        dp[i] += s[i]*i; //这s[i]个数都会与a[i]产生大小为a[i]的公因数
        for(int j = 2*i; j < maxn; j+=i)//枚举a[i]的所有倍数
            dp[i] = max(dp[i], dp[j]+(s[i]-s[j])*i);
        
        ans = max(ans, dp[i]);
    
    cout<<ans<<"\\n";
    return 0;



以上是关于Codeforces Round #757 (Div. 2)ABCD1的主要内容,如果未能解决你的问题,请参考以下文章

Codeforces Round #757 (Div. 2)ABCD1

Codeforces Round #757 div.2 A-D题解

Codeforces Round #757 div.2 A-D题解

Codeforces Round #391 div1 757F (Dominator Tree)

Codeforces Round #436 E. Fire(背包dp+输出路径)

[ACM]Codeforces Round #534 (Div. 2)