• Vases and Flowers (二分 + 线段树)


    题目链接:https://vjudge.net/contest/332656#problem/H

     题意:

    n个花瓶,m个操作,花瓶里面有的有花,有的是空的。

    1 x y 表示从第x个位置开始查y多花,若一朵花也插不上输出"Can not put any one.",反之输出插花的左位置和右位置。

    2 操作是清除区间[a,b]的花。并输出清除了多少花。

    思路:
    线段树维护区间,然后每次二分查找满足要求的第一个位置。

      1 #include <math.h>
      2 #include <stdio.h>
      3 #include <stdlib.h>
      4 #include <iostream>
      5 #include <algorithm>
      6 #include <string>
      7 #include <string.h>
      8 #include <vector>
      9 #include <map>
     10 #include <stack>
     11 #include <set>
     12 #include <random>
     13 
     14 #define ll long long
     15 const int maxn = 1e5 + 10;
     16 
     17 int n,m;
     18 
     19 struct Node {
     20     int l,r;
     21     int val;
     22     int lazy;
     23 }tree[maxn<<2];
     24 
     25 void build(int l,int r,int nod) {
     26     tree[nod].l = l;
     27     tree[nod].r = r;
     28     if (l == r ) {
     29         tree[nod].lazy = -1;
     30         return ;
     31     }
     32     int mid = (l + r) >> 1;
     33     build(l,mid,nod<<1);
     34     build(mid+1,r,(nod<<1)+1);
     35 }
     36 
     37 void pushdown(int nod) {
     38     tree[nod<<1].val = tree[nod].lazy*(tree[nod<<1].r-tree[nod<<1].l+1);
     39     tree[(nod<<1)+1].val = tree[nod].lazy*(tree[(nod<<1)+1].r-tree[(nod<<1)+1].l+1);
     40     tree[nod<<1].lazy = tree[(nod<<1)+1].lazy = tree[nod].lazy;
     41     tree[nod].lazy = -1;
     42 }
     43 
     44 void modify(int x,int y,int z,int nod=1) {
     45     int l = tree[nod].l,r = tree[nod].r;
     46     if (x <= l && y >= r) {
     47         tree[nod].lazy = z;
     48         tree[nod].val = (r-l+1)*z;
     49         return ;
     50     }
     51     if (tree[nod].lazy != -1 ) {
     52         pushdown(nod);
     53     }
     54     int mid = (l + r) >> 1;
     55     if (x <= mid) {
     56         modify(x,y,z,nod<<1);
     57     }
     58     if (y > mid) {
     59         modify(x,y,z,(nod<<1)+1);
     60     }
     61     tree[nod].val = tree[nod<<1].val + tree[(nod<<1)+1].val;
     62 }
     63 
     64 int query(int x,int y,int nod=1) {
     65     int l = tree[nod].l,r = tree[nod].r;
     66     if (x <= l && y >= r) {
     67         return tree[nod].val;
     68     }
     69     if (tree[nod].lazy != -1 ) {
     70         pushdown(nod);
     71     }
     72     int mid = (l + r ) >> 1;
     73     int sum = 0;
     74     if (x <= mid) {
     75         sum += query(x,y,nod<<1);
     76     }
     77     if (y > mid) {
     78         sum += query(x,y,(nod<<1)+1);
     79     }
     80     tree[nod].val = tree[nod<<1].val + tree[(nod<<1)+1].val;
     81     return sum;
     82 }
     83 
     84 int find(int s,int num ) {  // 查找满足从s开始插入num个的右边第一个位置
     85     int temp = query(s,n,1);
     86     if (temp == n-s+1) {
     87         return -1;
     88     }
     89     if (n-s+1-temp < num) {
     90         num = n-s+1-temp;
     91     }
     92     int l = s,r = n;
     93     int mid,d;
     94     int f = -1;
     95     while (l <= r) {
     96         mid = (l + r) >> 1;
     97         d = mid-s+1-query(s,mid);
     98         if (d > num) {
     99             r = mid - 1;
    100         }
    101         else if (d < num) {
    102             l = mid + 1;
    103         }
    104         else {
    105             f = mid;
    106             r = mid - 1;
    107         }
    108     }
    109     return f;
    110 }
    111 
    112 int main() {
    113     int T;
    114     scanf("%d",&T);
    115     while (T--) {
    116         memset(tree,0, sizeof(tree));
    117         scanf("%d%d",&n,&m);
    118         n--;
    119         build(0,n,1);
    120         while (m--) {
    121             int d,x,y;
    122             scanf("%d%d%d",&d,&x,&y);
    123             if (d == 1) {
    124                 int temp = find(x,1);
    125                 if (temp == -1) {
    126                     printf("Can not put any one.
    ");
    127                 }
    128                 else {
    129                     int end = find(x,y);
    130                     printf("%d %d
    ",temp,end);
    131                     modify(temp,end,1);
    132                 }
    133             }
    134             else {
    135                 printf("%d
    ",query(x,y));
    136                 modify(x,y,0);
    137             }
    138         }
    139         printf("
    ");
    140     }
    141     return 0;
    142 }
  • 相关阅读:
    省选模拟27
    省选模拟26
    省选模拟25
    省选模拟23
    PHP 各个框架的优缺点(超详细)
    windows 下安装中文版Git
    支付宝APP支付里设置应用网关和授权回调地址是不必填的
    linux服务器下安装phpstudy 如何命令行进入mysql
    js金钱转大写
    多个 (li) 标签如何获取获取选中的里面的某个特定值??
  • 原文地址:https://www.cnblogs.com/-Ackerman/p/11729075.html
Copyright © 2020-2023  润新知