zoukankan      html  css  js  c++  java
  • hdu 4288 Coder

      线段树好题,和 15 年的广东省省赛 C 题有相似之处,一开始我的思路有偏差,看了别人的博客后感觉处处技巧都是精华,主要是区间合并的技巧一时很难想到,先附上代码:

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<algorithm>
     4 using namespace std;
     5 #define  root  int rt, int l, int r
     6 #define  lson  rt << 1, l, mid
     7 #define  rson  rt << 1 | 1, mid + 1, r
     8 #define  makemid  int mid = l + r >> 1
     9 typedef long long LL;
    10 const int N = 100005;
    11 
    12 int cnt[N << 2];
    13 LL sum[N << 2][5];
    14 
    15 void build(root) {
    16     cnt[rt] = 0;
    17     for(int i = 0; i < 5; ++i)
    18         sum[rt][i] = 0;
    19     if(l == r)   return ;
    20     makemid;
    21     build(lson);
    22     build(rson);
    23 }
    24 
    25 inline int mymod(int x, int mod) {
    26     if(x < 0)   return (x % mod + mod) % mod;
    27     return  x % mod;
    28 }
    29 
    30 inline void pushup(int rt) {
    31     for(int i = 0; i < 5; ++i)
    32         sum[rt][i] = sum[rt << 1][i] + sum[rt << 1 | 1][mymod(i - cnt[rt << 1], 5)];
    33 }
    34 
    35 bool flag;
    36 int pos, val;
    37 
    38 void update(root) {
    39     flag ? ++cnt[rt] : --cnt[rt];
    40     if(l == r) {
    41         sum[rt][1] = flag ? val: 0;
    42         return ;
    43     }
    44     makemid;
    45     if(pos <= mid)    update(lson);
    46     else    update(rson);
    47     pushup(rt);
    48 }
    49 
    50 int find(int *c, int low, int up, int x) {
    51     int mid;
    52     while(low <= up) {
    53         mid = low + up >> 1;
    54         if(x == c[mid])    return mid;
    55         else if(x < c[mid])    up = mid - 1;
    56         else    low = mid + 1;
    57     }
    58     return low;
    59 }
    60 
    61 char op[N][5];
    62 int c[N], digit[N];
    63 
    64 int main() {
    65     int n,k;
    66     while(~scanf("%d",&n)) {
    67         k = 0;
    68         for(int i = 0; i < n; ++i) {
    69             scanf("%s",op[i]);
    70             if(op[i][0] != 's') {
    71                 scanf("%d", c + i);
    72                 digit[k++] = c[i];
    73             }
    74         }
    75         sort(digit, digit + k);
    76         int len = unique(digit, digit + k) - digit;
    77 
    78         if(len)   build(1,1,len);
    79 
    80         for(int i = 0; i < n; ++i) {
    81             if(op[i][0] == 's')   printf("%I64d
    ",sum[1][3]);
    82             else {
    83                 flag = op[i][0] == 'a';
    84                 pos = find(digit, 0, len - 1, c[i]) + 1;
    85                 val = c[i];
    86                 update(1,1,len);
    87             }
    88         }
    89     }
    90     return 0;
    91 }

      做 100 道水题,不如做一道难题来得更有意义。

  • 相关阅读:
    hdu 2647 Reward
    hdu 2094 产生冠军
    hdu 3342 Legal or Not
    hdu 1285 确定比赛名次
    hdu 3006 The Number of set
    hdu 1429 胜利大逃亡(续)
    UVA 146 ID Codes
    UVA 131 The Psychic Poker Player
    洛谷 P2491消防 解题报告
    洛谷 P2587 [ZJOI2008]泡泡堂 解题报告
  • 原文地址:https://www.cnblogs.com/Newdawn/p/4760806.html
Copyright © 2011-2022 走看看