ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

2021“MINIEYE杯”中国大学生算法设计超级联赛(2)1011.I love max and multiply (思维,位运算)

2021-07-30 17:34:20  阅读:194  来源: 互联网

标签:love gcd int max cin multiply const include define


  • 题意:有两个长度为\(n\)的序列\(a\)和\(b\),定义\(C_k=max(A_i,B_j)\ (i\ and\ j\ge k)\),求\(\sum^{n-1}_{i=0}C_i\).

  • 题解:暴力思路:求出所有的\(C_k\),然后从\(n-1\)倒着维护最大值贡献给答案即可.

    根据到这维护最大值这个思想,我们考虑\(i\)&\(j\)=\(i\)的情况,根据&运算的性质,两个数&之后只会不变或者变小,我们倒着枚举\(i\),根据上述性质,我们找\([i,n-1]\)中满足条件的\(j\),这里我们只要看单独的某一个\(1\)即可,可以用dp转移过来,那么我们每次可以得到\([i,n-1]\)中的满足条件的\(j\),更新最大值最小值.最后在求答案贡献的时候,\(A[i]\)表示的是\([i,n-1]\)中的\(i\)&\(j\)=\(i\)的某个位置\(x_1\)的值,同理,\(B[i]\)表示的是某个位置\(x_2\)的值,因为我们在更新的时候保证\(i\)&\(j\)=\(i\),且根据性质\(j\)一定不小于\(i\),那么\(x_1\)&\(x_2\ge i\),然后就根据我们前面的暴力思路求贡献给答案就好了.

  • 代码:

    #include <iostream>
    #include <iomanip>
    #include <cstdio>
    #include <cstring>
    #include <cmath>
    #include <algorithm>
    #include <stack>
    #include <queue>
    #include <vector>
    #include <map>
    #include <set>
    #include <unordered_set>
    #include <unordered_map>
    #define ll long long
    #define db double
    #define fi first
    #define se second
    #define pb push_back
    #define me memset
    #define rep(a,b,c) for(int a=b;a<=c;++a)
    #define per(a,b,c) for(int a=b;a>=c;--a)
    const int N = 1e6 + 10;
    const int mod = 998244353;
    const int INF = 0x3f3f3f3f;
    using namespace std;
    typedef pair<int,int> PII;
    typedef pair<ll,ll> PLL;
    int gcd(int a,int b){return b?gcd(b,a%b):a;}
    int lcm(int a,int b){return a/gcd(a,b)*b;}
    
    ll a[N],A[N],b[N],B[N];
    
    int main() {
        ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
        #ifdef lr001
            freopen("/Users/somnus/Desktop/data/in.txt","r",stdin);
        #endif
        #ifdef lr002
            freopen("/Users/somnus/Desktop/data/out.txt","w",stdout);
        #endif
        int _;
        cin>>_;
        while(_--){
            int n;
            cin>>n;
            rep(i,0,n-1) cin>>a[i],A[i]=a[i];
            rep(i,0,n-1) cin>>b[i],B[i]=b[i];
            int base=0;
            while((1<<base)<=n) base++;  //要包括n
            /* brute_force
            rep(i,0,n-1){
                rep(j,0,n-1){
                    res[i&j]=max(res[i&j],a[i]*b[j]);
                }
            }
            int ans=0;
            per(i,n-1,0){
                res[i]=max(res[i],res[i+1]);
                ans+=res[i];
            }
            cout<<ans<<'\n';
            */
            rep(i,n,(1<<base)-1){
                A[i]=B[i]=-INF;
                a[i]=b[i]=INF;
            }
            per(i,n,0){
                rep(j,0,base-1){
                    int cur=1<<j;
                    if((i&cur)==0){
                        A[i]=max(A[i],A[i^cur]);
                        B[i]=max(B[i],B[i^cur]);
                        a[i]=min(a[i],a[i^cur]);
                        b[i]=min(b[i],b[i^cur]);
                    }
                }
            }
            ll mx=-1e18;
            ll ans=0;
            per(i,n-1,0){
                ll res=-1e18;
                res=max(res,A[i]*B[i]);
                res=max(res,A[i]*b[i]);
                res=max(res,a[i]*B[i]);
                res=max(res,a[i]*b[i]);
                res=max(res,mx);
                mx=res;
                ans=(ans+res+mod)%mod;
            }
            cout<<ans<<'\n';
        }
    
    
    
        return 0;
    }
    
    

标签:love,gcd,int,max,cin,multiply,const,include,define
来源: https://www.cnblogs.com/lr599909928/p/15080639.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有