zoukankan      html  css  js  c++  java
  • ACM-ICPC 2017 西安赛区现场赛 K. LOVER II && LibreOJ#6062. 「2017 山东一轮集训 Day2」Pair(线段树)

    题目链接:西安:https://nanti.jisuanke.com/t/20759   (计蒜客的数据应该有误,题目和 LOJ 的大同小异,题解以 LOJ 为准)

            LOJ:https://loj.ac/problem/6062

    题意:给出一个长度为n的数列a_i和一个长度为m的数列b_i求a_i有多少个长度为m的连续子数列能与b_i匹配。 两个数列可以匹配,当且仅当存在一种方案,使两个数列中的数可以两两配对,两个数可以配对当且仅当它们的和不小于h。

    题解:先对 b 数组进行排序,建一颗线段树,将 b 数组中位置为 i 的数初始化为 -i ,那么当 [1,m] 中最小值大于等于 0 时即可匹配。枚举 a 的左端点,同时记录满足条件的最小右端点,当右端点 - 左端点 = m 时子区间满足条件 ans++。(西安现场赛的题则记录左端点可以匹配的最小右端点即可)

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 #define ll long long
     4 #define ull unsigned long long
     5 #define mst(a,b) memset((a),(b),sizeof(a))
     6 #define mp(a,b) make_pair(a,b)
     7 #define pi acos(-1)
     8 #define pii pair<int,int>
     9 #define pb push_back
    10 const int INF = 0x3f3f3f3f;
    11 const double eps = 1e-6;
    12 const int MAXN = 15e4 + 10;
    13 const int MAXM = 2e6 + 10;
    14 
    15 int a[MAXN], b[MAXN];;
    16 int st[MAXN << 2], lazy[MAXN << 2];
    17 
    18 void pushup(int rt) {
    19     st[rt] = min(st[rt << 1],st[rt << 1 | 1]);
    20 }
    21 
    22 void build(int rt,int l,int r) {
    23     if(l == r) {
    24         st[rt] = -l;
    25         return ;
    26     }
    27     int mid = (l + r) >> 1;
    28     build(rt << 1,l,mid);
    29     build(rt << 1 | 1,mid + 1,r);
    30     pushup(rt);
    31 }
    32 
    33 void pushdown(int rt) {
    34     if(lazy[rt]) {
    35         lazy[rt<<1] += lazy[rt], lazy[rt<<1|1] += lazy[rt];
    36         st[rt<<1] += lazy[rt], st[rt<<1|1] += lazy[rt];
    37         lazy[rt] = 0;
    38     }
    39 }
    40 
    41 void update(int rt,int l,int r,int ql,int qr,int val) {
    42     if(qr < ql) return ;
    43     if(ql <= l && qr >= r) {
    44         st[rt] += val;
    45         lazy[rt] += val;
    46         return ;
    47     }
    48     pushdown(rt);
    49     int mid = (l + r) >> 1;
    50     if(ql <= mid) update(rt<<1,l,mid,ql,qr,val);
    51     if(qr > mid) update(rt<<1|1,mid+1,r,ql,qr,val);
    52     pushup(rt);
    53 }
    54 
    55 int query(int rt,int l,int r,int ql,int qr) {
    56     if(ql <= l && qr >= r) return st[rt];
    57     int mid = (l + r) >> 1;
    58     int ans = 1e9;
    59     if(ql <= mid) ans = min(ans,query(rt<<1,l,mid,ql,qr));
    60     if(qr > mid) ans = min(ans,query(rt<<1|1,mid+1,r,ql,qr));
    61     return ans;
    62 }
    63 
    64 int main() {
    65 #ifdef local
    66     freopen("data.txt", "r", stdin);
    67 //    freopen("data.txt", "w", stdout);
    68 #endif
    69     int n,m,h;
    70     scanf("%d%d%d",&n,&m,&h);
    71     for(int i = 1; i <= m; i++) scanf("%d",&b[i]);
    72     for(int i = 1; i <= n; i++) scanf("%d",&a[i]);
    73     sort(b + 1, b + 1 + m);
    74     build(1,1,m);
    75     int now = 0, ans = 0;
    76     for(int i = 1; i <= n; i++) {
    77         while(query(1,1,m,1,m) < 0 && now < n) {
    78             int val = a[++now];
    79             int pos = lower_bound(b + 1, b + 1 + m, h - val) - b;
    80             update(1,1,m,pos,m,1);
    81         }
    82         if(query(1,1,m,1,m) >= 0 && now == i + m - 1) ans++;
    83         int pos = lower_bound(b + 1, b + 1 + m, h - a[i]) - b;
    84         update(1,1,m,pos,m,-1);
    85     }
    86     printf("%d
    ",ans);
    87     return 0;
    88 }
  • 相关阅读:
    两数相除(leetcode29)
    基本数据类型与包装数据类型的使用标准
    BigDecimal
    整型包装类值的比较
    实现strStr()(leetcode28)
    移除数组(leetcode27)
    删除排序数组中的重复项(leetcode26)
    mybatis.xml配置文件详解
    多表连接
    动态SQL
  • 原文地址:https://www.cnblogs.com/scaulok/p/9698776.html
Copyright © 2011-2022 走看看