• Codeforces Global Round 1 A~F


    失踪人口回来写题了。。

    写了几乎一下午。贴一贴代码以及口糊一下。

     A、

      题意:计算一下这个多项式的和。

      题解:暴力算一算对每一项异或一下。

    #include<bits/stdc++.h>
    using namespace std;
    int b,k;
    int kk[100005];
    int main()
    {
        cin>>b>>k;
        for(int i=0;i<k;i++)cin>>kk[k-i];
        int flag=0;
        for(int i=1;i<=k;i++)
        {
            if(i==1)
            {
                int tmp=kk[i]%2;
                flag^=tmp;
                continue;
            }
            if(b%2==0)
            {
                int tmp=0;
                flag^=tmp;
            }
            else
            {
                int tmp=kk[i]%2;
                flag^=tmp;
            }
        }
        if(flag)
        {
            cout<<"odd
    ";
        }
        else cout<<"even
    ";
    }
    

     B、

       题意:用k条线段覆盖n个递增的点,求线段总长最短是多少。

       题解:因为有k条线段所以有k-1个间隔,然后自然就是差分一下排个序找一下这些间隔点,然后从前往后在间隔点加一下。

    #include<bits/stdc++.h>
    #include<complex>
    #define db double
    #define ll long long
    #define mp make_pair
    #define fi first
    #define pb push_back
    #define se second
    #define rep(i,a,b)for(int i=a;i<=b;i++)
    using namespace std;
    const double pi=acos(-1);
    const int maxn=1e5+7;
    inline ll read()
    {
        ll x=0,f=1;char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
        return x*f;
    }
    int n,m,k;
    int vs[maxn];
    struct node
    {
        int id,val;
        friend bool operator<(node a,node b)
        {
            return a.val>b.val;
        }
    }vv[maxn];
    int cnt=0;
    int vis[maxn];
    int main()
    {
        int i;
        n=read();m=read();k=read();
        int las=0;
    
        for(i=0;i<n;i++)
        {
            vs[i]=read();
            if(i==0)las=vs[i];
            vv[i].val=vs[i]-las;
            las=vs[i];
            vv[i].id=i;
        }
        sort(vv,vv+n);
        for(i=0;i<k-1;i++)
        {
            if(vv[i].id==0)vis[vv[i].id]=1;
            else vis[vv[i].id-1]=1;
            //cout<<vv[i].id-1<<"
    ";
        }
        las=vs[0];
        ll ans=0;
        for(int i=0;i<n;i++)
        {
            if(vis[i])
            {
                ans+=vs[i]-las+1;
                las=vs[i+1];
            }
        }
        ans+=vs[n-1]-las+1;
        cout<<ans<<"
    ";
    }
    

      

     C、

      题意:f(a)=maxgcd(ab,a&b) 就是给你一个a然后找一个0<b<a使得这个式子最大。

      题解:随便试一试就发现一些异或和与的性质起到了作用。就如果不是2^x-1那答案就是它。因为可以弄成0和7。如果是2^x-1那ans=max gcd(2^x-1-b,b),

    这个东西sqrt(n)枚举一下最大因子,因为可以分成两部分就行。

    #include<bits/stdc++.h>
    #include<complex>
    #define db double
    #define ll long long
    #define mp make_pair
    #define fi first
    #define pb push_back
    #define se second
    #define rep(i,a,b)for(int i=a;i<=b;i++)
    using namespace std;
    const double pi=acos(-1);
    const int maxn=1e5+7;
    inline ll read()
    {
        ll x=0,f=1;char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
        return x*f;
    }
    int k;
    int main()
    {
        int q=read();
        while(q--)
        {
            k=read();
            int st=2;
            int flag=1;
            for(int i=2;i<=25;i++)
            {
                st*=2;
                if(k==st-1){flag=0;break;}
                if(k<st-1){break;}
            }
            if(flag){cout<<st-1<<"
    ";continue;}
            for(int i=2;i<=sqrt(k+0.5);i++)
            {
                if(k%i==0)
                {
                    cout<<k/i<<"
    ";
                    flag=1;
                    break;
                }
            }
            if(!flag)cout<<1<<"
    ";
        }
    }
    

      

     D、

      开始不会做的题了。

      题意:就给了一堆数字,问组成三个相邻数或者三个相同数字,这样最多能组成多少个三元组。

      题解:这种题第一眼肯定以为是排个序然后怎么贪心嘛。随便试了试过不了样例,瞄一眼发现是dp。想了好久发现想不清楚,做法也假了。就感觉一维是不够的但好像2维也没什么用,答案是三维。。。其实这个做法挺直觉也挺神的,如果三元组数量多于三个就显然可以退化成三个aaabbbccc这样子。所以可以%3,一个位置有影响的就三个情况,它作为最左,中间,最右,因而dp[n][3][3]。Tutorial的思想就是定义dp[i][t1][t2]。那么就能转移动dp[i+1][t2][t3]。初始值好像怎么设都能过。但是从一些非法转移的角度应该设负无穷?我一直没弄明白很多dp里初始值的问题。。。 

      

    #include<bits/stdc++.h>
    #include<complex>
    #define db double
    #define ll long long
    #define mp make_pair
    #define fi first
    #define pb push_back
    #define se second
    #define rep(i,a,b)for(int i=a;i<=b;i++)
    using namespace std;
    const double pi=acos(-1);
    const int maxn=1e5+7;
    inline ll read()
    {
        ll x=0,f=1;char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
        return x*f;
    }
    int k;
    int main()
    {
        int q=read();
        while(q--)
        {
            k=read();
            int st=2;
            int flag=1;
            for(int i=2;i<=25;i++)
            {
                st*=2;
                if(k==st-1){flag=0;break;}
                if(k<st-1){break;}
            }
            if(flag){cout<<st-1<<"
    ";continue;}
            for(int i=2;i<=sqrt(k+0.5);i++)
            {
                if(k%i==0)
                {
                    cout<<k/i<<"
    ";
                    flag=1;
                    break;
                }
            }
            if(!flag)cout<<1<<"
    ";
        }
    }
    

      

     E、

      题意:给两个序列,问能否通过a(i)'=a(i+1)+a(i-1)-a(i)这个操作把一个变成另一个。

      题解:考虑差分序列。。。。。然后就猜猜猜,注意要特判原序列的头尾。具体推导当然是看的题解。。话说,这种题以前是看到有人说要去想差分的。

      

    #include<bits/stdc++.h>
    #include<complex>
    #define db double
    #define ll long long
    #define mp make_pair
    #define fi first
    #define pb push_back
    #define se second
    #define rep(i,a,b)for(int i=a;i<=b;i++)
    using namespace std;
    const double pi=acos(-1);
    const int maxn=1e5+7;
    inline ll read()
    {
        ll x=0,f=1;char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
        return x*f;
    }
    ll a[maxn],b[maxn],c[maxn],d[maxn];
    int n;
    int main()
    {
        n=read();
        for(int i=1;i<=n;i++)
        {
            a[i]=read();
        }
        for(int i=1;i<=n;i++)b[i]=read();
        a[0]=b[0]=0;
        for(int i=1;i<=n;i++)c[i]=a[i]-a[i-1],d[i]=b[i]-b[i-1];
        sort(c+1,c+1+n);sort(d+1,d+1+n);
        int flag=0;
        for(int i=1;i<=n;i++)
        {
            if(c[i]!=d[i]){flag=1;break;}
        }
        if(!flag&&a[1]==b[1]&&a[n]==b[n])cout<<"Yes
    ";
        else cout<<"No
    ";
    }
    

      

      F、

      题意:给一颗树,然后dfs序就是1~N。Q次询问,每个询问回答一个点到(l,r)区间内中叶子节点距离的最小值。

      题解:离线做法,就如果所询问的区间不在这个子树中就是depth(x)+query(l,r)这样的一个东西。如果是在子树中那就是query(l,r)-depth(x)。像树剖那样子,肯定形成了一个连续的区间,所以考虑用线段树进行处理。第一遍dfs将叶子的值设为深度,非叶子inf。然后第二遍dfs时在dfs一个节点的某个儿子时,将线段树这个子树区间剪掉2*w,w是这条边的权值。此时所有情况都是depth(x)+query(l,r)。因为只有他的子树是被减去的,类似就是depth(x)+query'(l,r),其中query'(l,r)=query(l,r)-2*w。然后dfs完这个子树后再加回去。效果其实就是depth(x)+query(l,r)-2*depth(lca)。所以感觉会树上差分+dfs什么的应该能想到。感觉自己一知半解,只会写代码。

    题解:感觉这个lca什么的叙述有问题,还是按照更general的方法写一下,就是当你dfs一个点的某个子节点时,对于该子节点的这颗子树中的所有节点来说,换根后深度都要剪掉w,而到其余点的深度要加上w。所以可以给这个区间剪掉2w,在统计答案时把多剪掉的这部分答案加上,多剪掉的实则是在从1一直dfs到v这条链上每条边的权值,也就是在1为根时v这个点的深度。

      

    #include<bits/stdc++.h>
    #include<complex>
    #define db double
    #define ll long long
    #define mp make_pair
    #define fi first
    #define pb push_back
    #define se second
    #define rep(i,a,b)for(int i=a;i<=b;i++)
    #define ls (x<<1)
    #define rs (x<<1|1)
    using namespace std;
    const double pi=acos(-1);
    const int maxn=5e5+7;
    inline ll read()
    {
        ll x=0,f=1;char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
        return x*f;
    }
    ll val[maxn<<2],laz[maxn<<2];
    int fiv[maxn],lav[maxn];
    vector<pair<int,ll> >vec[maxn];
    vector<int>Q[maxn];
    int L[maxn],R[maxn];
    ll ans[maxn];
    ll depth[maxn];
    int cnt;
    int n,q;
    void push_down(int x)
    {
        if(laz[x])
        {
            val[ls]+=laz[x];
            laz[ls]+=laz[x];
            val[rs]+=laz[x];
            laz[rs]+=laz[x];
            laz[x]=0;
        }
    }
    void update(int x,int l,int r,int L,int R,ll tt)
    {
        if(L<=l&&r<=R)
        {
            val[x]+=tt;laz[x]+=tt;
            return;
        }
        push_down(x);
        int mid=(l+r)>>1;
        if(L<=mid)update(ls,l,mid,L,R,tt);
        if(R>mid)update(rs,mid+1,r,L,R,tt);
        val[x]=min(val[ls],val[rs]);
    }
    ll query(int x,int l,int r,int L,int R)
    {
        if(L<=l&&r<=R)
        {
            return val[x];
        }
        push_down(x);
        int mid=(l+r)>>1;
        ll res=1e18;
        if(L<=mid)res=min(res,query(ls,l,mid,L,R));
        if(R>mid)res=min(res,query(rs,mid+1,r,L,R));
        return res;
    }
    void dfs1(int x)
    {
        fiv[x]=++cnt;
        if(!vec[x].size())update(1,1,n,fiv[x],fiv[x],depth[x]);
        else update(1,1,n,fiv[x],fiv[x],1e18);
        for(int i=0;i<(int)vec[x].size();i++)
        {
            int tt=vec[x][i].fi;ll w=vec[x][i].se;
            depth[tt]=depth[x]+w;dfs1(tt);
        }
        lav[x]=cnt;
    }
    void dfs2(int x)
    {
        for(int i=0;i<(int)Q[x].size();i++)
        {
            int tt=Q[x][i];
            ans[tt]=depth[x]+query(1,1,n,L[tt],R[tt]);
        }
        for(int i=0;i<(int)vec[x].size();i++)
        {
            int tt=vec[x][i].fi;ll w=vec[x][i].se;
            update(1,1,n,fiv[tt],lav[tt],-2*w);
            dfs2(tt);
            update(1,1,n,fiv[tt],lav[tt],2*w);
        }
    }
    int main()
    {
        n=read();q=read();
        int pi,wi;
        for(int i=2;i<=n;i++)
        {
            pi=read();wi=read();
            vec[pi].pb(mp(i,wi));
        }
        for(int i=1;i<=q;i++)
        {
            pi=read();Q[pi].pb(i);
            L[i]=read();R[i]=read();
        }
        dfs1(1);
        dfs2(1);
        for(int i=1;i<=q;i++)cout<<ans[i]<<"
    ";
    }
    

      

      

      

      

  • 相关阅读:
    css自定义字体
    nuxt按需引入 element-UI、自定义主题色(终极按需引入)
    Vue 拖拽组件 vuedraggable 和 awe-dnd
    css 0.5px
    react取消监听scroll事件
    vue使用jsonp
    nuxt使用QRCode.js 生成二维码
    阻止冒泡
    nuxt.js配置BASE_URL(基本域名)和NODE_ENV(环境变量)
    Numpy基础学习笔记1
  • 原文地址:https://www.cnblogs.com/intwentieth/p/10357840.html
Copyright © 2020-2023  润新知