其他分享
首页 > 其他分享> > 9.3

9.3

作者:互联网

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