首页 > 其他分享 >8.17

8.17

时间:2022-08-17 22:13:07浏览次数:54  
标签:int long leq 8.17 lcm oplus define

CF1718A

题意:

给定一个序列,每次可以花费\(\lceil\frac{r-l+1}{2}\rceil\)的代价选择一段区间\([l,r]\),并把区间里的每个数字异或上\(x\),最少花费多少代价可以让整个序列变成\(0\)?

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

题解:

区间异或可以想到前缀异或和。

而且这个上取整性质说明区间长度是\(2\)的倍数会很赚,而且可以每次只选长度为\(1\)和\(2\)的区间,更大的区间可以由此拼来。

那么假如有\(a,b,c,d\)序列,最坏情况下要\(4\)秒完成。

那么怎么才能优化到\(3\)秒呢,当然是每次选长度为\(2\)的区间。

假如第一次异或完是\(0,a\oplus b,c,d\)

第二次\(0,0,a\oplus b\oplus c,d\)

第三次\(0,0,0,a\oplus b\oplus c\oplus d\)

如果三次可以完成,那么必然有\(a\oplus b\oplus c\oplus d=0\)

也就是这一段的异或和为\(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=1e9+7,inv2=5e8+4,inf=2e15;
    void __init(int n=2000) {}
    
    inline void main()
    {
        int n;
        cin>>n;
        vector<int> a(n+2),b(n+2);
        for(int i=1;i<=n;++i)
        {
            cin>>a[i];
            b[i]=b[i-1]^a[i];
        }
        map<int,int> q;
        vector<int> dp(n+1);
        q[0]=0;
        dp[0]=0;
        for(int i=1;i<=n;++i)
        {
            dp[i]=dp[i-1];
            if(q.find(b[i])!=q.end())
            {
                dp[i]=max(dp[i],dp[q[b[i]]]+1);
            }
            q[b[i]]=i;
        }
        cout<<n-dp[n]<<'\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;
}
/*

*/

CF1718C

题意:

给定一个长度为\(n\)的循环序列,请你给出两个数字\(1\leq s\leq n,1\leq k<n\),满足从\(s\)开始,每次向后走\(k\)步,执行\(n\)次,走过的位置权值之和最大,求最大的权值和。

有\(m\)次修改操作,每次修改一个位置上的数字。

\(1\leq n,m\leq 2*10^5\)

题解:

其实可以发现本质不同的走法都是\(n\)的不同因子,这样就只有\(n\sqrt{n}\)种不同的序列了,但是要维护这些的最大值还要多个\(log\),很难通过。

其实可以不用,因为发现对每种质因子只要提取最大的一个因子出来而不用其他的因子,换句话说,有用的因子们,不存在一个是另一个的因子。

因为\(k\)越大,循环周期越短,就可以更高效率的走更大的数字。

#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=1e9+7,inv2=5e8+4,inf=2e15;
    void __init(int n=2000) {}
    
    inline void main()
    {
        int n,m;
        cin>>n>>m;
        vector<int> a(n+1);
        vector<vector<int> > ans(n+1);
        vector<int> d;
        int nn=n;
        for(int i=2;i<=nn;++i)
        {
            if(nn%i==0)
            {
                d.emplace_back(n/i);
                ans[n/i].resize(n/i);
                while(nn%i==0) nn/=i;
            }
        }
        sort(d.begin(),d.end());
        for(int i=0;i<n;++i)
        {
            cin>>a[i];
        }
        int s=d.size();
        multiset<int> q;
        for(int i=0;i<s;++i)
        {
            int len=d[i];
            for(int st=0;st<len;++st)
            {
                int pos=st,sum=0;
                while(pos<n)
                {
                    sum+=a[pos];
                    pos+=len;
                }
                ans[len][st]=sum*len;
                q.insert(ans[len][st]);
            }
        }
        cout<<*(q.rbegin())<<'\n';
        for(int tt=1;tt<=m;++tt)
        {
            int x,y;cin>>x>>y;
            --x;
            for(int i=0;i<s;++i)
            {
                int len=d[i];
                int st=x%len;
                q.erase(q.find(ans[len][st]));
                ans[len][st]-=a[x]*len;
                ans[len][st]+=y*len;
                q.insert(ans[len][st]);
            }
            a[x]=y;
            cout<<*(q.rbegin())<<'\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;
}
/*

*/

CF1712E

题意:

给定\(m\)个\(l,r\),求满足\(l\leq i<j<k\leq r\)且\(lcm(i,j,k)\geq i+j+k\)的数对的数量。

\(m\leq 2*10^5,1\leq l+2\leq r\leq 2*10^5\)

题解:

正难则反,首先所有数对的数量是\(\dbinom{r-l+1}{3}\)

然后减去不满足要求的,直觉发现\(lcm\)比\(i+j+k\)要大许多,不满足的数量不会太多。

不妨考虑\(lcm\)是多少,首先他们一定是\(k\)的倍数。

其次,\(i+j+k<k+k+k=3k\),所以可能的结果只有\(lcm=k\)或\(lcm=2k\)

当\(lcm=k\)时,一定满足\(i+j+k>lcm=k\),所以只要统计对每个\(k\)来说,有多少符合要求的\(i|k,j|k\)

当\(lcm=2*k\)时,要满足\(i+j+k>lcm=2k\),就要\(i+j>k\)

而且\(i\)和\(j\)至少有一个要比\(k\)多乘一个\(2\)。

不妨设\(i=a*k,j=b*k\),那么有\(a+b>1\)

而且至少有一个分子是\(2\)的倍数。

打个表可以发现,可行的情况只有

\(i=3*a,j=4*a,k=6*a,lcm=12*a\)

或者

\(i=5*a,j=6*a,k=15*a,lcm=30*a\)

接下来就是\(HH\)的项链,考验树状数组功底了。

#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=1e9+7,inv2=5e8+4,inf=2e15;
    void __init(int n=2000) {}
    
    inline void main()
    {
        int n=200000,m;
        cin>>m;
        vector<int> ans(m+1);
        struct node
        {
            int l,r,id;
            bool operator < (const node &t) const
            {
                return r<t.r;
            }
        };
        vector<node> a(m+1);
        for(int i=1;i<=m;++i)
        {
            cin>>a[i].l>>a[i].r;
            a[i].id=i;
        }
        sort(a.begin()+1,a.end());
        vector<vector<int> > d(n+1);
        vector<int> tr(n+1);
        auto update=[&](int x,int k) -> void
        {
            for(int i=x;i<=n;i+=lowbit(i)) tr[i]+=k;
        };
        auto query=[&](int x) -> int
        {
            int sum=0;
            for(int i=x;i;i-=lowbit(i)) sum+=tr[i];
            return sum;
        };
        for(int i=n;i>=1;--i)
        {
            for(int j=i+i;j<=n;j+=i)
            {
                d[j].emplace_back(i);
            }
        }
        int t=1;
        for(int i=1;i<=n;++i)
        {
            int cnt=0;
            for(int j:d[i])
            {
                update(j,cnt);
                ++cnt;
            }
            if((i*2)%12==0) update((i*2)/4,1);
            if((i*2)%30==0) update((i*2)/5,1);
            while(t<=m&&a[t].r<=i)
            {
                int len=a[t].r-a[t].l+1;
                ans[a[t].id]=len*(len-1)*(len-2)/6-(query(i)-query(a[t].l-1));
                ++t;
            }
        }
        for(int i=1;i<=m;++i) cout<<ans[i]<<'\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;
}
/*

*/

标签:int,long,leq,8.17,lcm,oplus,define
From: https://www.cnblogs.com/knife-rose/p/16596944.html

相关文章

  • 8.17总结
    自动刷题机\(solution\)二分答案找最大最小值考试时二分写错了ACCode#include<bits/stdc++.h>usingnamespacestd;#definelllonglonginlinellread(){ ll......
  • [游记]暑假集训5-2022.8.17
    今天的题目都比较有思维量,嗯A.星际旅行考虑一下去掉那两条有向边,就是一个典型的欧拉回路然后问的就是能够生成的欧拉回路的个数考虑每次删掉两条边,有三种删除方法:$\q......
  • NOIP2022模拟赛二 By yzxoi 8.17
    Preface今天早上被公交车搞了,晚了30min才到……最后T1读入\(n\)的时候写%d了,喜提30pts(结果Rank竟然不变233)A.「NOIP2022模拟赛二ByyzxoiA」『Pale』/feat.初音ミ......
  • 摸鱼喽哈哈!!!8.17 写了就是我的
    1、一个数组,有很多个字典 长这样:data_list=[{'Type1':114,'Type2':514},{'Type1':1919,'Type2':810}]一般json获取的数据,就可能会长成这个样子,问题不大可以直接df一下......
  • 2022.8.17 vscode与nodejs
    大前端01、概述和前端工具vscode安装1.1、下载安装VScode下载地址:https://code.visualstudio.com/   1:双击打开vscode安装包2:指定安装目录     ......