ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

9.3

2022-09-04 01:03:08  阅读:147  来源: 互联网

标签:9.3 return int void long main define


ABC139F

题意:

给定\(n\)个向量,从中任意选择,最后组合起来的向量长度最长。

\(n\leq 100\)

题解:

神仙题。

肯定不会选两个方向差太多的向量。

所以把所有向量极角排序后,选择的向量是连续的一段。

注意要把排序后的向量数组延长一倍形成环。

#include<bits/stdc++.h>
using namespace std;
namespace red{
#define int long long
#define double long double
#define ls(p) (p<<1)
#define rs(p) (p<<1|1)
#define lowbit(i) ((i)&(-i))
#define mid ((l+r)>>1)
#define eps (1e-15)
    const int N=1e6+10,mod=998244353,inf=2e15;
    void __init(int n=2000) {}
    inline void main()
    {
        int n;
        cin>>n;
        typedef array<double,2> pr;
        vector<pr> a(2*n);
        for(int i=0;i<n;++i)
        {
            cin>>a[i][0]>>a[i][1];
        }
        sort(a.begin(),a.begin()+n,[&](pr x,pr y){return atan2(x[1],x[0])<atan2(y[1],y[0]);});
        for(int i=n;i<2*n;++i) a[i]=a[i-n];
        double ans=0;
        for(int i=0;i<n;++i)
        {
            double sumx=0,sumy=0;
            for(int j=i;j<i+n;++j)
            {
                sumx+=a[j][0],sumy+=a[j][1];
                ans=max(ans,sqrt(sumx*sumx+sumy*sumy));
            }
        }
        cout<<fixed<<setprecision(12)<<ans<<'\n';
    }
}
signed main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);cout.tie(0);
    red::__init();
    int qwq=1; //cin>>qwq;
    while(qwq--) red::main();
    return 0;
}
/*
1 7 5 6 8 2 6 5

0 8 5 6 8 0 8 5
3
5 6 5
3 8 5
2
3
8
*/

ABC140E

题意:

给定一个排列,求\(\sum_{l=1}^n\sum_{r=l+1}^nX_{l,r}\)

其中\(X_{l,r}\)是\(p[l]\sim p[r]\)中第二大的数字。

\(n\leq 10^5\)

题解:

考虑每个数字的贡献,它作为那些段的第二大数字。

设一个数字\(x\),位置在\(p\),左边第一个大于它的数字位置是\(l\),第二个是\(ll\),右边同理\(r,rr\)

那么它作为第二大,很明显左边或者右边只能有一个比自己大。

所以可行的范围,左端点取值在\((ll,l]\),右端点取值在\([p,r)\)

或者左端点在\((l,p]\),右端点在\([r,rr)\)

#include<bits/stdc++.h>
using namespace std;
namespace red{
#define int long long
#define double long double
#define ls(p) (p<<1)
#define rs(p) (p<<1|1)
#define lowbit(i) ((i)&(-i))
#define mid ((l+r)>>1)
#define eps (1e-15)
    const int N=1e6+10,mod=998244353,inf=2e15;
    void __init(int n=2000) {}
    inline void main()
    {
        int n;
        cin>>n;
        typedef array<int,2> pr;
        vector<pr> a(n+1);
        for(int i=1;i<=n;++i)
        {
            int x;cin>>x;
            a[i]=pr{x,i};
        }
        sort(a.begin()+1,a.end());
        reverse(a.begin()+1,a.end());
        multiset<int> q;
        q.insert(0),q.insert(0);
        q.insert(n+1),q.insert(n+1);
        int ans=0;
        for(int i=1;i<=n;++i)
        {
            int x=a[i][0],p=a[i][1];
            auto it=q.lower_bound(a[i][1]);
            int ll=0,l=0,r=n+1,rr=n+1;
            if(it!=q.end())
            {
                r=*it;
                ++it;
                if(it!=q.end()) rr=*it;
                --it;
            }
            if(it!=q.begin())
            {
                --it;
                l=*it;
                if(it!=q.begin())
                {
                    --it;
                    ll=*it;
                }
            }
            if(l>=1) ans+=max(0ll,(r-a[i][1])*(l-ll)*x);
            if(r<=n) ans+=max(0ll,(a[i][1]-l)*(rr-r)*x);
            q.insert(a[i][1]);
        }
        cout<<ans<<'\n';
    }
}
signed main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);cout.tie(0);
    red::__init();
    int qwq=1; //cin>>qwq;
    while(qwq--) red::main();
    return 0;
}
/*
1 7 5 6 8 2 6 5

0 8 5 6 8 0 8 5
3
5 6 5
3 8 5
2
3
8
*/

ABC141F

题意:

给\(n\)个数,把他们分成两组,两组各自异或起来,再把两组的异或和加起来,求最大值

\(n\leq 10^5,0\leq a_i<2^{60}\)

题解:

很神。

这种题按位考虑

如果这一位有奇数个\(1\),不管怎么分,这一位的贡献都是\(1\),不用考虑这些位

如果有偶数个\(1\),不管怎么分,这一位的异或和都是\(0\)。

也就是说第一组的异或和一定等于第二组的异或和。

所以就是用线性基求个最大值就行了。

#include<bits/stdc++.h>
using namespace std;
namespace red{
#define int long long
#define double long double
#define ls(p) (p<<1)
#define rs(p) (p<<1|1)
#define lowbit(i) ((i)&(-i))
#define mid ((l+r)>>1)
#define eps (1e-15)
    const int N=1e6+10,mod=998244353,inf=2e15;
    void __init(int n=2000) {}
    inline void main()
    {
        int n;
        cin>>n;
        vector<int> a(n);
        vector<int> s(60);
        for(int i=0;i<n;++i)
        {
            cin>>a[i];
            for(int k=0;k<60;++k) s[k]+=(a[i]>>k)&1;
        }
        vector<int> p(60);
        auto insert=[&](int x) -> void
        {
            for(int k=59;~k;--k) if((x>>k)&1)
            {
                if(!p[k]) {p[k]=x;return;}
                x^=p[k];
            }
        };
        auto query=[&]() -> int
        {
            int x=0;
            for(int k=59;~k;--k)
            {
                x=max(x,x^p[k]);
            }
            return x;
        };
        int ans=0;
        for(int k=0;k<60;++k)
        {
            if(s[k]&1) ans|=(1ll<<k);
        }
        for(int i=0;i<n;++i)
        {
            int x=a[i];
            for(int k=0;k<60;++k) if(s[k]&1)
            {
                x&=(-1)^(1ll<<k);
            }
            insert(x);
        }
        cout<<ans+2*query()<<'\n';
    }
}
signed main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);cout.tie(0);
    red::__init();
    int qwq=1; //cin>>qwq;
    while(qwq--) red::main();
    return 0;
}
/*
1 7 5 6 8 2 6 5

0 8 5 6 8 0 8 5
3
5 6 5
3 8 5
2
3
8
*/

标签:9.3,return,int,void,long,main,define
来源: https://www.cnblogs.com/knife-rose/p/16654091.html

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

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

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

ICode9版权所有