• GYM 101350 F. Monkeying Around(线段树 or 思维)


    F. Monkeying Around
    time limit per test
    2.0 s
    memory limit per test
    256 MB
    input
    standard input
    output
    standard output

    When the monkey professor leaves his class for a short time, all the monkeys go bananas. N monkeys are lined up sitting side by side on their chairs. They each have the same joke book. Before the professor returns, M jokes were heard.

    Each of the M jokes are said in the order given and have the following properties:

    xi - position of the monkey who said it.

    li – index of the joke in the book.

    ki – volume the monkey says that joke.

    When the monkey at position xi says the joke li, all monkeys at a distance less than or equal to ki from that monkey (including the monkey who said the joke) will fall off their chairs in laughter if they have never heard the joke li before.

    If the joke li has been heard anytime during the past before, and the monkey hears it again, then he will sit back up in his chair.

    A monkey can fall off his chair more than once (every time he hears a new joke), and if he is already on the ground and hears a new joke, he will stay on the ground.

    Can you figure out how many monkeys will be in their seats by the time the professor comes back?

    Input

    The first line of input is T – the number of test cases.

    The first line of each test case is N, M (1 ≤ N ≤ 105) (1 ≤ M ≤ 105) – the number of monkeys in the class, and the number of jokes said before the professor returns.

    The next M lines contain the description of each joke: xi, li, ki (1 ≤ xi ≤ N) (1 ≤ li ≤ 105) (0 ≤ ki ≤ N).

    Output

    For each test case, output on a line a single integer - the number of monkeys in their seats after all jokes have been said.

    Example
    Input
    1
    10 7
    3 11 0
    3 11 2
    5 12 1
    8 13 2
    7 11 2
    10 12 1
    9 12 0
    Output
    3
    






    我开始傻×的把操作存了起来,然后按笑话的种类排序,可是后来发现不能这么做啊,室友先后顺序的!!
    因为每一只猴子的最后的状态要看他最后一次听到的笑话是什么,然后再看这个笑话听到了几次若果是==1,就从椅子下来。

    第一步求每一只猴子最后听到那种笑话:首先可以线段树,然后也可以set求
    第二部 求每一只猴子最后一次听到的笑话的种类的数量
    有两种方法!
    1: for每一只猴子,然后在猴子的位置上对每种笑话进行查分,num【i】 保存每种颜色的数量
    2:for每一个笑话的种类,在for在这个种类上的猴子并查询

    第一种码:
      1 #include <iostream>  
      2 #include <cstdio>  
      3 #include <cstring>  
      4 #include <string>  
      5 #include <algorithm>  
      6 #include <cmath>  
      7 #include <map>  
      8 #include <set>  
      9 #include <stack>  
     10 #include <queue>  
     11 #include <vector>  
     12 #include <bitset>  
     13 #include <functional>  
     14  
     15 using namespace std;
     16  
     17 #define LL long long  
     18 const int INF = 0x3f3f3f3f;
     19 const int maxn = 1e5 + 10;
     20  
     21 int n, m, x, y, z;
     22 int a[maxn << 2], lazy[maxn << 2];
     23 int sum[maxn];
     24 vector<pair<int, int> > g1[maxn];
     25 vector<int>g2[maxn];
     26  
     27 void build(int k, int l, int r)
     28 {
     29     a[k] = lazy[k] = 0;
     30     if (l == r) return;
     31     int mid = (l + r) / 2;
     32     build(k << 1, l, mid);
     33     build(k << 1 | 1, mid + 1, r);
     34 }
     35  
     36 void pushDown(int k)
     37 {
     38     a[k << 1] = a[k << 1 | 1] = lazy[k];
     39     lazy[k << 1] = lazy[k << 1 | 1] = lazy[k];
     40     lazy[k] = 0;
     41 }
     42  
     43 void update(int k, int l, int r, int ll, int rr, int val)
     44 {
     45     if (ll <= l && r <= rr)
     46     {
     47         a[k] = lazy[k] = val;
     48         return;
     49     }
     50     int mid = (l + r) / 2;
     51     if (lazy[k]) pushDown(k);
     52     if (ll <= mid) update(k << 1, l, mid, ll, rr, val);
     53     if (rr > mid)  update(k << 1 | 1, mid + 1, r, ll, rr, val);
     54 }
     55  
     56 int get(int k, int l, int r, int p)
     57 {
     58     if (l == r) return a[k];
     59     int mid = (l + r) / 2;
     60     if (lazy[k]) pushDown(k);
     61     if (p <= mid) return get(k << 1, l, mid, p);
     62     return get(k << 1 | 1, mid + 1, r, p);
     63 }
     64  
     65 int lowbit(int k)
     66 {
     67     return k & -k;
     68 }
     69  
     70 void update(int k, int val)
     71 {
     72     for (int i = k; i < maxn; i += lowbit(i))
     73         sum[i] += val;
     74 }
     75  
     76 int getsum(int k)
     77 {
     78     int ans = 0;
     79     for (int i = k; i; i -= lowbit(i))
     80         ans = ans + sum[i];
     81     return ans;
     82 }
     83  
     84 int main()
     85 {
     86     int t;
     87     scanf("%d", &t);
     88     while (t--)
     89     {
     90         scanf("%d%d", &n, &m);
     91         for (int i = 0; i < maxn; i++)
     92         {
     93             g1[i].clear();
     94             g2[i].clear();
     95         }
     96         build(1, 1, n);
     97         for (int i = 1; i <= m; i++)
     98         {
     99             scanf("%d%d%d", &x, &y, &z);
    100             int L = max(1, x - z);
    101             int R = min(n, x + z);
    102             update(1, 1, n, L, R, y);
    103             g1[y].push_back(make_pair(L, R));
    104         }
    105         for (int i = 1; i <= n; i++)
    106         {
    107             int k = get(1, 1, n, i);
    108             g2[k].push_back(i);
    109         }
    110         int ans = g2[0].size();
    111         for (int i = 1; i < maxn; i++)
    112         {
    113             int Size1 = g1[i].size(), Size2 = g2[i].size();
    114             if (Size1 == 0 || Size2 == 0) continue;
    115             for (int j = 0; j < Size1; j++)
    116             {
    117                 pair<int, int>p = g1[i][j];
    118                 update(p.first, 1);
    119                 update(p.second + 1, -1);
    120             }
    121             for (int j = 0; j < Size2; j++)
    122             {
    123                 int p = g2[i][j];
    124                 if (getsum(p) >= 2) ans++;
    125             }
    126             for (int j = 0; j < Size1; j++)
    127             {
    128                 pair<int, int>p = g1[i][j];
    129                 update(p.first, -1);
    130                 update(p.second + 1, 1);
    131             }
    132         }
    133         printf("%d
    ", ans);
    134     }
    135     return 0;
    136 }

    第二种:

     1 #include<cstdio>
     2 #include<iostream>
     3 #include<set>
     4 #include<vector>
     5 #include<cstring>
     6 #include<string>
     7 #include<algorithm>
     8 using namespace std;
     9 const int maxn=100000+10;
    10 set<int> s;
    11 vector<int> G[maxn];
    12 int n,m,num[maxn],type[maxn];
    13 int main(void)
    14 {
    15     int xx,ll,kk,T,ans;
    16     cin>>T;
    17     while(T--)
    18     {
    19         ans=0;
    20         for(int i=0;i<maxn;i++)
    21             G[i].clear();
    22         s.clear();
    23         memset(num,0,sizeof(num));
    24         scanf("%d%d",&n,&m);
    25         for(int ii=1;ii<=m;ii++)
    26         {
    27             scanf("%d%d%d",&xx,&ll,&kk);
    28             type[ii]=ll;
    29             int lend=max(1,xx-kk);
    30             int rend=min(n,xx+kk);
    31             G[lend].push_back(ii);
    32             G[rend+1].push_back(-ii);
    33         }
    34         for(int i=1;i<=n;i++)
    35         {
    36             for(auto it:G[i])
    37             {
    38                 if(it>0)//This is the begin position for a joke
    39                 {
    40                     s.insert(it);
    41                     num[type[it]]++;
    42                 }
    43                 else
    44                 {
    45                     s.erase(-it);
    46                     num[type[-it]]--;
    47                 }
    48             }
    49             if(s.empty())
    50                 ans++;//important! No jokes at all
    51             else
    52             {
    53                 auto it=s.end();
    54                 it--;
    55                 if(num[type[*it]]>1)
    56                     ans++;
    57             }
    58         }
    59         cout<<ans<<endl;
    60     }
    61     return 0;
    62 }
     1 #include<cstdio>
     2 #include<iostream>
     3 #include<set>
     4 #include<vector>
     5 #include<cstring>
     6 #include<string>
     7 #include<algorithm>
     8 using namespace std;
     9 const int maxn=100000+10;
    10 set<int> s;
    11 vector<int> G[maxn];
    12 int n,m,num[maxn],type[maxn];
    13 int main(void)
    14 {
    15     int xx,ll,kk,T,ans;
    16     cin>>T;
    17     while(T--)
    18     {
    19         ans=0;
    20         for(int i=0;i<maxn;i++)
    21             G[i].clear();
    22         s.clear();
    23         memset(num,0,sizeof(num));
    24         scanf("%d%d",&n,&m);
    25         for(int ii=1;ii<=m;ii++)
    26         {
    27             scanf("%d%d%d",&xx,&ll,&kk);
    28             type[ii]=ll;
    29             int lend=max(1,xx-kk);
    30             int rend=min(n,xx+kk);
    31             G[lend].push_back(ii);
    32             G[rend+1].push_back(-ii);
    33         }
    34         for(int i=1;i<=n;i++)
    35         {
    36             for(auto it:G[i])
    37             {
    38                 if(it>0)//This is the begin position for a joke
    39                 {
    40                     s.insert(it);
    41                     num[type[it]]++;
    42                 }
    43                 else
    44                 {
    45                     s.erase(-it);
    46                     num[type[-it]]--;
    47                 }
    48             }
    49             if(s.empty())
    50                 ans++;//important! No jokes at all
    51             else
    52             {
    53                 auto it=s.end();
    54                 it--;
    55                 if(num[type[*it]]>1)
    56                     ans++;
    57             }
    58         }
    59         cout<<ans<<endl;
    60     }
    61     return 0;
    62 }



















  • 相关阅读:
    02 _ 该如何选择消息队列
    封装、抽象、继承、多态分别可以解决哪些编程问题?
    04 _ 理论一:当谈论面向对象的时候,我们到底在谈论什么?
    03 _ 面向对象、设计原则、设计模式、编程规范、重构,这五者有何关系?
    接口使用
    结构体和方法
    通道的高级玩法
    通道的基本操作
    极客时间 mp3提取
    iOS多线程中的单例
  • 原文地址:https://www.cnblogs.com/zhangbuang/p/10525490.html
Copyright © 2020-2023  润新知