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\n";
    }
    else cout<<"even\n";
}

 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<<"\n";
    }
    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<<"\n";
}

  

 C、

  题意:f(a)=maxgcd(a⊕b,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<<"\n";continue;}
        for(int i=2;i<=sqrt(k+0.5);i++)
        {
            if(k%i==0)
            {
                cout<<k/i<<"\n";
                flag=1;
                break;
            }
        }
        if(!flag)cout<<1<<"\n";
    }
}

  

 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<<"\n";continue;}
        for(int i=2;i<=sqrt(k+0.5);i++)
        {
            if(k%i==0)
            {
                cout<<k/i<<"\n";
                flag=1;
                break;
            }
        }
        if(!flag)cout<<1<<"\n";
    }
}

  

 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\n";
    else cout<<"No\n";
}

  

  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什么的应该能想到。感觉自己一知半解,只会写代码。

  

#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]<<"\n";
}

  

  

  

  

原文地址:https://www.cnblogs.com/intwentieth/p/10357840.html

时间: 2024-10-09 18:16:56

Codeforces Global Round 1 A~F的相关文章

Codeforces Global Round 1 (A-E题解)

Codeforces Global Round 1 题目链接:https://codeforces.com/contest/1110 A. Parity 题意: 给出{ak},b,k,判断a1*b^(k-1)+a2*b^(k-2)+...+ak*b^0的奇偶性. 题解: 暴力求模2意义下的值就好了. 代码如下: #include <bits/stdc++.h> using namespace std; typedef long long ll; const int N = 2e5+5; int

【手抖康复训练1 】Codeforces Global Round 6

[手抖康复训练1 ]Codeforces Global Round 6 总结:不想复习随意打的一场,比赛开始就是熟悉的N分钟进不去时间,2333,太久没写题的后果就是:A 题手抖过不了样例 B题秒出思路手抖过不了样例,C题秒出思路手抖过不了样例*3 D题 手抖 过的了样例 ,调了1h,赛后发现变量名写错了,改一个字符就能AC... 题目等补完题一起放上来QAQ 原文地址:https://www.cnblogs.com/ttttttttrx/p/12110199.html

[codeforces]Codeforces Global Round 1 F. Nearest Leaf

题解:  语文题????  上面说的一段代码 告诉你的是  节点编号顺序与dfs序顺序一致  也就是你  dfs序以后编号就是[1,n]  根据这个特性  那么我们只需要维护每个叶子节点到查询v的距离即可  那么我们只需要离线所有查询 然后对子树修改即可   用线段树来维护区间加和区间最小值就行 #include <algorithm> #include <iostream> #include <cstring> #include <cstdio> #inc

[Codeforces]Codeforces Global Round 1

A - Parity 题意 给定一个$b$进制数,要求输出它在十进制下是奇数还是偶数. 分析 花了我略多的时间,首先题目中给的数字范围很大,不能直接转化为10进制. 分析性质,发现只有奇数乘奇数还是奇数,其他都是偶数. 对奇数进制和偶数进制分类讨论. 偶数进制看最低位的奇偶性,如果是奇数那么这个数就是奇数,不然是偶数. 奇数进制看每一位上奇数的个数,如果是奇数个奇数就是奇数,不然是偶数. 代码 1 #include <bits/stdc++.h> 2 using namespace std;

Codeforces Global Round 1

A. Parity 签. 1 #include <bits/stdc++.h> 2 using namespace std; 3 4 #define N 100010 5 int b, k, a[N]; 6 7 int main() 8 { 9 while (scanf("%d%d", &b, &k) != EOF) 10 { 11 int res = 0; 12 for (int i = 1; i <= k; ++i) scanf("%d&

Codeforces Global Round 1 自闭记

A:签到. #include<iostream> #include<cstdio> #include<cmath> #include<cstdlib> #include<cstring> #include<algorithm> using namespace std; #define ll long long char getc(){char c=getchar();while ((c<'A'||c>'Z')&&a

Codeforces Global Round 1 做题记录

A. 题解:快速幂 代码: 1 #include<bits/stdc++.h> 2 #define ll long long 3 #define maxn 100005 4 using namespace std; 5 const ll mod=2; 6 ll b,k; 7 ll a[maxn]; 8 ll fastpow(ll a,ll p) 9 { 10 ll ans=1; 11 while(p) 12 { 13 if(p&1)ans=ans*a%mod; 14 a=a*a%mod

codeforces global round 1题解搬运

A,B很简单,跳过了. C题规律相当明显,可以直接对\(2^n-1\)打表,也可以不打表直接算最大因数. D题两种操作转化一下DP即可. E题考虑查分数组不变的性质. F题考虑dfs时动态维护每个叶子的深度,从一个节点走向它的孩子相当于孩子对应的区间加,不包含孩子的区间减. #include <bits/stdc++.h> using namespace std; typedef long long ll; const int P=1050000; const int N=500010; in

C. Meaningless Operations Codeforces Global Round 1 异或与运算,思维题

C. Meaningless Operations time limit per test 1 second memory limit per test 256 megabytes input standard input output standard output Can the greatest common divisor and bitwise operations have anything in common? It is time to answer this question.