Codeforces 1168 C And Reachability —— DP

202 篇文章 5 订阅

This way

题意:

现在有n个数,如果第a[i]&a[j]>0&&i<j,那么位置i就可以跳到位置j,现在每次都问你第x位到第y个位置中能否找到一个序列使得可以从位置x跳到位置y。

题解:

对于这道题目,我们需要知道每一个位置的每一位可以到达哪里,那么
dp[i][j]表示距离位置i最近的可到达的存在1<<j这一位的位置最大是多少。
而不是最前面,因为如果知道了最后能到哪的话,前面拥有第i位的地方就可以以那一位为跳板跳过来。
那么当前位置拥有的位数能够到达的最后的地方就是这个位置,对于其它位,我们枚举拥有的位,看这个位能够跳的前面的地方所拥有的最后的含有当前没有的位的位置(有点绕)美也就是状态转移。
那么对于输入的x,y如果当前位x有并且y能够到达的地方>=x,说明x能够通过dp[y][i]跳过来。

#include<bits/stdc++.h>
using namespace std;
const int N=3e5+5;
int dp[N][25],pos[25],a[N];
int main()
{
    int n,q;
    scanf("%d%d",&n,&q);
    for(int i=1;i<=n;i++){
        scanf("%d",&a[i]);
        for(int j=0;j<=20;j++){
            if(a[i]&(1<<j))
                dp[i][j]=i;
            else{
                for(int k=0;k<=20;k++)
                    if(a[i]&(1<<k))
                        dp[i][j]=max(dp[i][j],dp[pos[k]][j]);
            }
        }
        for(int j=0;j<=20;j++)
            if(a[i]&(1<<j))
                pos[j]=i;
    }
    while(q--){
        int x,y;
        scanf("%d%d",&x,&y);
        int f=0;
        for(int i=0;i<=20;i++)
            if(a[x]&(1<<i)&&dp[y][i]>=x)
                f=1;
        printf("%s\n",f?"Shi":"Fou");
    }
    return 0;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值