zoukankan      html  css  js  c++  java
  • 洛谷P2073 送花 [2017年6月计划 线段树01]

    P2073 送花

    题目背景

    小明准备给小红送一束花,以表达他对小红的爱意。他在花店看中了一些花,准备用它们包成花束。

    题目描述

    这些花都很漂亮,每朵花有一个美丽值W,价格为C。

    小明一开始有一个空的花束,他不断地向里面添加花。他有以下几种操作:

    操作 含义

    1 W C 添加一朵美丽值为W,价格为C的花。

    3 小明觉得当前花束中最便宜的一朵花太廉价,不适合送给小红,所以删除最便宜的一朵花。

    2 小明觉得当前花束中最贵的一朵花太贵,他心疼自己的钱,所以删除最贵的一朵花。

    -1 完成添加与删除,开始包装花束

    若删除操作时没有花,则跳过删除操作。

    如果加入的花朵价格已经与花束中已有花朵价格重复,则这一朵花不能加入花束。

    请你帮小明写一个程序,计算出开始包装花束时,花束中所有花的美丽值的总和,以及小明需要为花束付出的总价格。

    输入输出格式

    输入格式:

    若干行,每行一个操作,以-1结束。

    输出格式:

    一行,两个空格隔开的正整数表示开始包装花束时,花束中所有花的美丽值的总和。以及小明需要为花束付出的总价格。

    输入输出样例

    输入样例#1:
    1 1 1
    1 2 5
    2
    1 3 3
    3
    1 5 2
    -1
    
    输出样例#1:
    8 5

    说明

    对于20%数据,操作数<=100,1<=W,C<=1000。

    对于全部数据,操作数<=100000,1<=W,C<=1000000。

    此题可谓练习线段树、Set、Treap、Splay的好题。

    线段树做法:离线读取所有添加数据和操作,删除的时候向下dfs结束后向上更新即可。需要维护四个值,耐心写!猥琐发育别浪!

    细节:别把美丽和价钱反了

       左移右移别手残(比如我)

         别忘了long long

    以上。

      1 #include <iostream>
      2 #include <cstdio>
      3 #include <cstring>
      4 #include <cstdlib>
      5 #include <algorithm>
      6 inline int max(int a,int b) {return a > b ? a : b;}
      7 inline int min(int a,int b) {return a > b ? b : a;}
      8 const int MAXN = 100000 + 10;
      9 inline void read(long long &x){
     10     x = 0;char ch = getchar();char c = ch;
     11     while(ch > '9' || ch < '0')c = ch, ch = getchar();
     12     while(ch >= '0' && ch <= '9')x = x * 10 + ch - '0',ch = getchar();
     13     if(c == '-')x = -x;
     14 }
     15 long long work[MAXN],num[MAXN][2],tmp,n,m;bool b[1000000 + 10];
     16 struct STNODE{
     17     long long l,r,max,min,sum,ssum;
     18 }stnode[(MAXN << 2 )+ 10];
     19 void build(int o = 1, int l = 1, int r = m){
     20     stnode[o].l = l;stnode[o].r = r;
     21     if(l == r){
     22         stnode[o].max = l;
     23         stnode[o].min = l;
     24         stnode[o].sum = num[l][1];
     25         stnode[o].ssum = num[l][0];
     26         return;
     27     }
     28     int mid = (l + r) >> 1;
     29     build(o << 1, l, mid);
     30     build(o << 1 | 1, mid + 1, r);
     31     if(num[stnode[o << 1].max][0] > num[stnode[o << 1 | 1].max][0])stnode[o].max = stnode[o << 1].max;
     32     else stnode[o].max = stnode[o << 1 | 1].max;    
     33     if(num[stnode[o << 1].min][0] < num[stnode[o << 1 | 1].min][0])    stnode[o].min = stnode[o << 1].min;
     34     else stnode[o].min = stnode[o << 1 | 1].min;    
     35     stnode[o].sum = stnode[o << 1].sum + stnode[o << 1 | 1].sum;
     36     stnode[o].ssum = stnode[o << 1].ssum + stnode[o << 1 | 1].ssum;
     37 }
     38 void cutoff(int p, int o = 1){
     39     int l = stnode[o].l;int r = stnode[o].r;
     40     if(l == r && l == p){
     41         stnode[o].ssum = stnode[o].sum = stnode[o].max = stnode[o].min = 0;
     42         return;
     43     }
     44     int mid = (l + r) >> 1;
     45     if(mid >= p) cutoff(p, o << 1);
     46     else cutoff(p, o << 1 | 1);
     47     stnode[o].sum = 0;
     48     stnode[o].ssum = 0;
     49     stnode[o].sum = stnode[o << 1].sum + stnode[o << 1 | 1].sum; 
     50     stnode[o].ssum = stnode[o << 1].ssum + stnode[o << 1 | 1].ssum; 
     51     if(num[stnode[o << 1].max][0] > num[stnode[o << 1 | 1].max][0]) stnode[o].max = stnode[o << 1].max;
     52     else stnode[o].max = stnode[o << 1 | 1].max;
     53     if(stnode[o << 1].min == 0 && stnode[o << 1 | 1].min == 0) stnode[o].min = 0;
     54     else if(stnode[o << 1].min == 0) stnode[o].min = stnode[o << 1 | 1].min;
     55     else if(stnode[o << 1 | 1].min == 0) stnode[o].min = stnode[o << 1].min;
     56     else {
     57         if(num[stnode[o << 1].min][0] < num[stnode[o << 1 | 1].min][0]) stnode[o].min = stnode[o << 1].min;
     58         else stnode[o].min = stnode[o << 1 | 1].min;
     59     }
     60 }
     61 int query_max(int ll,int rr,int o = 1){
     62     int ans1 = 0;int ans2 = 0;
     63     int l = stnode[o].l;int r = stnode[o].r;
     64     if(l >= ll && r <= rr) return stnode[o].max;
     65     int mid = (l + r) >> 1;
     66     if(mid >= ll) ans1 = query_max(ll, rr, o << 1);
     67     if(mid < rr) ans2 = query_max(ll, rr, o << 1 | 1);
     68     if(ans1 == 0 && ans2 == 0) return 0;
     69     if(num[ans1][0] > num[ans2][0]) return ans1;
     70     else return ans2;
     71 }
     72 int query_min(int ll,int rr,int o = 1){
     73     int ans1 = 0;int ans2 = 0;
     74     int l = stnode[o].l;int r = stnode[o].r;
     75     if(l >= ll && r <= rr) return stnode[o].min;
     76     int mid = (l + r) >> 1;
     77     if(mid >= ll) ans1 = query_min(ll, rr, o << 1);
     78     if(mid < rr) ans2 = query_min(ll, rr, o << 1 | 1);
     79     if(ans1 == 0 && ans2 == 0) return 0;
     80     else if(ans1 == 0) return ans2;
     81     else if(ans2 == 0) return ans1;
     82     else {
     83         if(num[ans1][0] < num[ans2][0]) return ans1;
     84         else return ans2;
     85     }
     86 }
     87 int main(){
     88         read(tmp);
     89     while(tmp != -1){
     90         n ++;
     91         if(tmp == 1){m ++;read(num[m][1]);read(num[m][0]);}
     92         else if(tmp == 2) work[n] = 1;
     93         else work[n] = 2;
     94         read(tmp);
     95     }
     96     if(m >= 1) build();
     97     int j = 0;int len = 0;
     98     for(int i = 1;i <= n;i ++){
     99         if(work[i] == 1 && len < j){
    100             int a = query_max(1, j);
    101             cutoff(a);
    102             b[num[a][0]] = false;
    103             len ++;
    104         }
    105         else if(work[i] == 2 && len < j){
    106             int a = query_min(1, j);
    107             cutoff(a);
    108             b[num[a][0]] = false;
    109             len ++;
    110         }
    111         else if(!work[i]){
    112             j ++;
    113             if(!b[num[j][0]]) b[num[j][0]] = true;
    114             else cutoff(j);
    115         }
    116     }
    117     printf("%lld %lld", stnode[1].sum, stnode[1].ssum);
    118     return 0;
    119 }
  • 相关阅读:
    在Ubuntu下安装软件
    HIVE Thrift Server使用总结
    用Wubi来安装Ubuntu 12
    linux命令总结
    Linux Sed简介
    Linux批量重命名文件
    算法学习的轨迹(转)
    写入es速率优化
    走近Flex组件系列(三):按扭组件(Button,CheckBox,LinkBar,LinkButton,PopUpButton,RadioButton,ToggleButtonBar)
    走近Flex组件系列(二):简单实用的Alert组件
  • 原文地址:https://www.cnblogs.com/huibixiaoxing/p/6959437.html
Copyright © 2011-2022 走看看