zoukankan      html  css  js  c++  java
  • 【BZOJ5194】Snow Boots

    【原题题面】传送门

    【简化题意】

    给定一个长度为n的序列。 有m次询问,每次询问给定两个数si,di。你一开始站在0,每次你可以走不超过di,但你到达的位置的数不能超过si。问能否走到n+1。 n,m<=100000。

    【未讲之前】不知道这题哪里跟线段树挂钩了,感觉跟线段树八竿子打不着的关系23333

    【题解】先根据s[i]的限制确定出哪些地方是不能走的,然后按s[i]从小到大排序,维护n上不能走的最长连续长度,因为每一次s[i]越来越大,那么限制越来越小。

    还有弄清楚只要最长连续不能走的长度小于相应的d[i]就一定能走。这是因为每次能走的长度是1~d[i],所以我可以通过一定的调整使每次面临的都是最长连续长度的困难。

    【讲了之后】按照s[i]排序离线这一点没想到哇。还有就是这题的切入口不是怎么线段树,而是理解题意之后想怎么维护不能走的最长连续长度,然后才想到可以用线段树。看网上还有题解说可以用set的,也可以实现的吧。

    【具体实现】维护最长连续的长度,需要维护当前结点的范围内最长连续不能走的长度sz。

    更新这个值需要max,lmax,rmax;

    【code】

    #include<bits/stdc++.h>
    using namespace std;
    
    inline int read()
    {
        int N=0,C=0;char tf=getchar();
        for(;!isdigit(tf);tf=getchar())C|=tf=='-';
        for(;isdigit(tf);tf=getchar())N=(N<<1)+(N<<3)+(tf^48);
        return C?-N:N;
    }
    
    const int N=100010;
    int n,q,ans[N];
    struct nc
    {
        int i,s,d;//id step deep
        friend bool operator <(nc a,nc b){return a.d==b.d?a.s<b.s:a.d<b.d;}//先放砖
        nc(int i=0,int s=0,int d=0):i(i),s(s),d(d){}
    }a[N<<1];
    struct tf
    {
        int m,l,r,s;//max lmax rmax size
    }t[N<<2];
    
    void B(int l,int r,int p)
    {
        t[p].m=t[p].l=t[p].r=t[p].s=r-l+1;
        if(l==r)return;
        int m=l+r>>1;
        B(l,m,p<<1),B(m+1,r,p<<1|1);
    }
    
    void U(int l,int r,int p,int x)
    {
        if(l==r){t[p].m=t[p].l=t[p].r=0;return;}
        int m=l+r>>1;x<=m?U(l,m,p<<1,x):U(m+1,r,p<<1|1,x);
    
        t[p].l=t[p<<1].l==t[p<<1].s?t[p<<1].s+t[p<<1|1].l:t[p<<1].l;
        t[p].r=t[p<<1|1].r==t[p<<1|1].s?t[p<<1|1].s+t[p<<1].r:t[p<<1|1].r;
    
        t[p].m=max(t[p<<1].m,t[p<<1|1].m);
        t[p].m=max(t[p].m,t[p<<1].r+t[p<<1|1].l);
    }
    
    int main()
    {
        n=read(),q=read(),B(1,n,1);
        for(int i=1,d;i<=n;++i)d=read(),a[i]=nc(i,0,d);
        for(int i=1,d,s;i<=q;++i)s=read(),d=read(),a[i+n]=nc(i,d,s);
        sort(a+1,a+n+q+1);
    
        for(int i=1;i<=n+q;++i)
        {
            if(!a[i].s)U(1,n,1,a[i].i);
            else ans[a[i].i]=t[1].m<a[i].s;
        }
        for(int i=1;i<=q;++i)printf("%d
    ",ans[i]);
    
        return 0;
    }
    View Code

    我的代码不知怎么就是调不出来#¥%……&*),上面是豆哥的。

    G102的孤儿们都要好好的啊。
  • 相关阅读:
    Java集合框架--List 遍历
    Java集合框架--List 类
    Leetcode 239 Sliding Window Maximum (指定滑动窗最大值) (滑动窗口)
    Vim配置
    子字符串模板 (双指针, 滑动窗口)
    Leetcode 76 Minimum Window Substring. (最小窗口子字符串) (滑动窗口, 双指针)
    Leetcode 3 Longest Substring Without Repeating Characters. (最长无重复字符子串) (滑动窗口, 双指针)
    一切从赞美开始
    Leetcode 10 regular expression matching (正则表达式匹配) (动态规划)
    Leetcode 5 Longest Palindromic Substring (最长回文子字符串)(动态规划)
  • 原文地址:https://www.cnblogs.com/ve-2021/p/10387209.html
Copyright © 2011-2022 走看看