zoukankan      html  css  js  c++  java
  • 牛客练习赛14 B 倍增 E bitset

    B 区间的连续段
    链接:https://www.nowcoder.com/acm/contest/82/B
    来源:牛客网

    题目描述

    给你一个长为n的序列a和一个常数k

    有m次询问,每次查询一个区间[l,r]内所有数最少分成多少个连续段,使得每段的和都 <= k

    如果这一次查询无解,输出"Chtholly"
    输入描述:

    第一行三个数n,m,k
    第二行n个数表示这个序列a
    之后m行,每行给出两个数l r表示一次询问

    输出描述:

    输出m行,每行一个整数,表示答案

    示例1
    输入

    5 5 7
    2 3 2 3 4
    3 3
    4 4
    5 5
    1 5
    2 4

    输出

    1
    1
    1
    2
    2

    备注:

    对于100%的数据,1 <= n , m <= 1000000 , 1 <= ai , k <= 1000000000

    tags:
    dp[i][j] 表示第 i 个数往后走 2^j 段能到达第几个数,所以转移即 dp[i][j] = dp[dp[i][j-1]][j-1] ,查询时只要倍增跳着找即可。

    //https://www.nowcoder.com/acm/contest/82/B
    #include<bits/stdc++.h>
    using namespace std;
    #pragma comment(linker, "/STACK:102400000,102400000")
    #define rep(i,a,b) for (int i=a; i<=b; ++i)
    #define per(i,b,a) for (int i=b; i>=a; --i)
    #define mes(a,b)  memset(a,b,sizeof(a))
    #define INF 0x3f3f3f3f
    #define MP make_pair
    #define PB push_back
    #define fi  first
    #define se  second
    #define  mid  (l+(r-l)/2)
    typedef long long ll;
    const int N = 1000005;
    
    int n, m, dp[N][21], k, a[N];
    ll  sum[N];
    int solve(int l, int r) {
        int ret = 1;
        for(int j=20; dp[l][0]<=r; --j) {
            if(dp[l][j]<=r) {
                l = dp[l][j];
                ret += (1<<j);
            }
        }
        return ret;
    }
    int vis[N];
    int main()
    {
        scanf("%d%d%d", &n, &m, &k);
        int ai;
        rep(i,1,n) {
            scanf("%d", &a[i]), sum[i]=sum[i-1]+a[i];
            vis[i] = vis[i-1]+(a[i]>k);
        }
        mes(dp, INF);
        rep(i,1,n)
        {
            int pos = upper_bound(sum+1, sum+1+n, sum[i-1]+k) - sum;
            dp[i][0] = pos;
        }
        for(int j=0; (1<<j)<=n; ++j)
        {
            rep(i,1,n)
            {
                if(dp[i][j-1]<=n)
                    dp[i][j] = dp[dp[i][j-1]][j-1];
            }
        }
        int l, r;
        while(m--)
        {
            scanf("%d%d", &l, &r);
            if(vis[r]-vis[l-1]>0) puts("Chtholly");
            else printf("%d
    ", solve(l, r));
        }
    
        return 0;
    }
    
    

    E 无向图中的最短距离
    链接:https://www.nowcoder.com/acm/contest/82/E
    来源:牛客网

    题目描述

    有一个n个点的无向图,有m次查询,每次查询给出一些(xi,yi)

    令dist(x,y)表示x和y点在图中最短距离,dist(x,x)=0,如果x,y不连通则dist(x,y) = inf

    每次查询图中有多少个点v与至少一个这次询问给出的(xi,yi)满足dist(v,xi)<=yi
    输入描述:

    第一行三个数表示n,m,q

    之后m行每行两个数x,y表示有一条x与y之间的边,边权为1

    之后q次询问,每个询问先给你一个数a
    之后一行2a个数,第2i-1个数xi和第2i个数yi表示一个二元组(xi,yi)

    输出描述:

    输出q行,每行一个数表示这次询问的答案

    示例1
    输入

    5 6 6
    2 3
    1 3
    2 5
    1 3
    3 2
    2 5
    1
    3 1
    1
    1 1
    1
    1 4
    1
    5 2
    1
    1 4
    2
    1 0 5 1

    输出

    3
    2
    4
    3
    4
    3

    备注:

    对于100%的数据,n <= 1000 , m <= 100000 , q <=
    100000
    a的和<= 2100000

    tags:
    先预处理出每个点到其它 n-1个点的最短距离,然后搞个 bitset<1000>bit[1000][1000] ,比如到点 u 的距离 <= x 的点 to 存入,即 bit[u][x].set(to) ,也就是把距离 <= 或者 > 两种可能性存入进去。 bitset 是按位储存的, bitset<1000> 只有1000位(实际应该会按字节扩充一点),所以是可以储存下的。

    //https://www.nowcoder.com/acm/contest/82/E
    #include<bits/stdc++.h>
    using namespace std;
    #pragma comment(linker, "/STACK:102400000,102400000")
    #define rep(i,a,b) for (int i=a; i<=b; ++i)
    #define per(i,b,a) for (int i=b; i>=a; --i)
    #define mes(a,b)  memset(a,b,sizeof(a))
    #define INF 0x3f3f3f3f
    #define MP make_pair
    #define PB push_back
    #define fi  first
    #define se  second
    typedef long long ll;
    const int N = 1005;
    
    bitset<N> bit[N][N], bit1;
    int n, m;
    vector< int > G[N];
    
    int dis[N];  bool inq[N];  queue< int > q;
    void spfa(int st)
    {
        while(!q.empty()) q.pop();
        mes(dis, INF);
        dis[st] = 0;
        q.push(st);
        while(!q.empty())
        {
            int u = q.front();  q.pop();
            inq[u] = false;
            for(int to : G[u])
            {
                if(dis[to] > dis[u]+1)
                {
                    dis[to] = dis[u]+1;
                    if(inq[to]==false) inq[to]=true, q.push(to);
                }
            }
        }
        rep(i,1,n) if(dis[i]!=INF) bit[st][dis[i]].set(i);
        rep(i,1,n) bit[st][i] |= bit[st][i-1];
    }
    int main()
    {
        int Q;
        scanf("%d%d%d", &n, &m, &Q);
        int u, v;
        rep(i,1,m)
        {
            scanf("%d%d", &u, &v);
            G[u].PB(v), G[v].PB(u);
        }
        rep(i,1,n) spfa(i);
        int k, x, y;
        while(Q--)
        {
            bit1.reset();
            scanf("%d", &k);
            while(k--)
            {
                scanf("%d%d", &x, &y);
                bit1 |= bit[x][y];
            }
            printf("%d
    ", bit1.count());
        }
    
        return 0;
    }
    
    
  • 相关阅读:
    PDA设备小知识--(IP)工业防护等级含义
    实施项目--如何推进项目实施进度
    Git.Framework 框架随手记--存储过程简化
    Git.Framework 框架随手记--SQL配置文件的使用
    Git.Framework 框架随手记--ORM查询数据集合 二
    介绍 Scratch 3.0:扩展编码创造力
    微服务架构:引领数字化转型的基石
    网易云技术开放日 云安全专场分享圆满结束
    JVM调优推荐
    springboot + mybatis + 多数据源
  • 原文地址:https://www.cnblogs.com/sbfhy/p/8732884.html
Copyright © 2011-2022 走看看