周中练习2题目整理

CodeForces - 983B


题意:定义一个异或和f(),f(1,2,4,8)=f(1^2,2^4,4^8)=f(3,6,12)=f(3^6,6^12)=f(5,10)=f(5^10)=f(15)。
思路:在纸上一写一下就可以发现dp[l][r]=dp[l+1][r]+dp[l][r-1]。然后在维护一个最大值。还是看代码吧


ll dp[5005][5005];
ll f[5005][5005];
ll n;
ll dfs(ll l,ll r)//先求区间异或
{
    //cout<<l<<" "<<r<<endl;
    if(dp[l][r]!=-1) return dp[l][r];
    dp[l][r]=(dfs(l,r-1)^dfs(l+1,r));
    return dp[l][r];
}
ll dfs2(ll l,ll r)//求此分支内的最大值
{
    if(f[l][r]!=-1) return f[l][r];
    f[l][r]=max(dp[l][r],max(dfs2(l+1,r),dfs2(l,r-1)));
    return f[l][r];
}
int main()
{
    memset(dp,-1,sizeof(dp));
    memset(f,-1,sizeof(f));
    scanf("%lld",&n);
    for(int i=1;i<=n;i++)
    {
        scanf("%lld",&dp[i][i]);
        f[i][i]=dp[i][i];
    }
    dfs(1,n);
    dfs2(1,n);
    int q;
    ll l,r;
    scanf("%d",&q);
    for(int i=1;i<=q;i++)
    {
        scanf("%lld%lld",&l,&r);
        cout<<f[l][r]<<endl;
    }
}


CodeForces - 873B


题意:给出一个n长度的01串,其中含有相同0,1个数的子串被称为“平衡串”,问最长的平衡串的长度。


思路:求前缀和,遇见1就+1,遇见0就-1,然后前缀和值相等的两个位置必定符合条件。


struct node
{
    int val;
    int id;
}mp[200005];
int n;
int a[100005];
char s[100005];
int main()
{
    scanf("%d",&n);
    scanf("%s",s);
    memset(mp,0,sizeof(mp));
    mp[100000].id=0;
    a[0]=0;
    int ans=0;
    for(int i=0;i<n;i++)
    {
        if(s[i]=='0') a[i+1]=a[i]-1;
        else a[i+1]=a[i]+1;
        if(mp[a[i+1]+100000].id==0)
        {
            if(a[i+1]==0)
            {
                int t=i+1-mp[a[i+1]+100000].id;
                if(t>ans) ans=t;
                continue;
            }
            mp[a[i+1]+100000].id=i+1;
        }
        else
        {
            int t=i+1-mp[a[i+1]+100000].id;
            if(t>ans) ans=t;
        }
    }
    cout<<ans<<endl;
}


CodeForces - 946C


题意:问能不能把给定串,变成另外一个串,使得“abcdefghijklmnopqrstuvwxyz”是它的子序列,操作是对原串任意字符做 +1 操作,不限次数。


思路:依次找a,b,c...更新就可以了


char s[100005];
int main()
{
    int i,j;
    scanf("%s",s);
    int n=strlen(s);
    bool f=0;
    char t='a';
    for(i=0;i<n;i++)
    {
        if(s[i]<=t)
        {
            s[i]=t;
            t=t+1;
        }
        if(t=='z'+1)
        {
            f=1;
            break;
        }
    }
    if(f==0)
        cout<<"-1"<<endl;
    else
    {
        for(i=0;i<n;i++)
            printf("%c",s[i]);
        printf("\n");
    }
    return 0;
}


CodeForces - 264B


给出n个数,利用这n个数构造一个好的序列,好的序列是单调增的,而且序列中相邻的两个元素都不互质,问最长的好序列的长度是多少。


来自:https://www.cnblogs.com/fu3638/p/9104307.html
设dp[x]表示以x为结尾的好序列的最长长度。
d[i]表示以i为因子的x中最大的dp[x]值。
于是得到状态转移方程dp[x]=max(dp[x],d[i]+1) (i是x的因子)
每次求出dp[x]还要顺便更新d[i],即d[i]=dp[x].


const int N=1e5+5;
const int INF=0x3f3f3f3f;
const double eps=1e-10;
vector<int>fat[N];
int a[N],d[N],dp[N];
int main()
{
    int n;
    cin>>n;
    for(int i=1;i<=n;i++)
    {
        cin>>a[i];
    }
    for(int i=2;i<=a[n];i++)
    {
        for(int j=i;j<=a[n];j+=i)
        {
            fat[j].push_back(i);
        }
    }
    int ans=0;
    for(int i=1;i<=n;i++)
    {
        //遍历因子
        for(int j=0;j<fat[a[i]].size();j++)
        {
            int t=fat[a[i]][j];
            dp[i]=max(dp[i],d[t]+1);
        }
        for(int j=0;j<fat[a[i]].size();j++)
        {
            int t=fat[a[i]][j];
            d[t]=dp[i];
        }
        ans=max(ans,dp[i]);
    }
    //只有1的时候ans为0,实际为1
    cout<<max(ans,1)<<endl;
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值