zoukankan      html  css  js  c++  java
  • Gym

      

    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 NM (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
    题意:
    一坨猴子坐在椅子上讲笑话,要是某只猴子听到的笑话它没听过,它就会坐到地上去,否则就坐在椅子上,问最后有多少个猴子坐在椅子上。
    思路:
    显而易见,猴子最后的状态之和猴子听到的最后一个笑话有关。
    所以当前问题就是,对于某一只猴子,它听到的最后一个笑话是几号笑话?这个笑话它之前有没有听过?
    对于第一个问题,用线段树区间染色。
    对于第二个问题,记录下每个笑话对应的猴子(就是猴子和它最后听的笑话相对应),每个笑话对应的区间。
    先区间更新笑话对应的区间,在查询对应的猴子听过这个笑话的次数。
    代码:
    我的代码是错的。
    但是仍然能够AC,因为数据没有存在某一个猴子没有听见笑话的情况。
    #include<iostream>
    #include<algorithm>
    #include<vector>
    #include<stack>
    #include<queue>
    #include<map>
    #include<set>
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<ctime>
    #define fuck(x) cout<<#x<<" = "<<x<<endl;
    #define ls (t<<1)
    #define rs ((t<<1)|1)
    using namespace std;
    typedef long long ll;
    typedef unsigned long long ull;
    const int maxn = 100086;
    const int inf = 2.1e9;
    const ll Inf = 999999999999999999;
    const int mod = 1000000007;
    const double eps = 1e-6;
    const double pi = acos(-1);
    
    struct node{
        int l,r;
        int num;
    }a[maxn<<3];
    
    void build(int t,int l,int r){
        a[t].l=l;a[t].r=r;
        a[t].num=0;
        if(l==r){a[t].num=-1;return;}
        int mid=(l+r)>>1;
        build(ls,l,mid);
        build(rs,mid+1,r);
    }
    
    void push_down(int t){
        a[ls].num=a[rs].num=a[t].num;
        a[t].num=0;
    }
    
    void update(int t,int l,int r,int num){
        if(a[t].num){push_down(t);}
        if(a[t].l==l&&a[t].r==r){
            a[t].num=num;
            return;
        }
        int mid=(a[t].l+a[t].r)>>1;
        if(mid>=r){update(ls,l,r,num);}
        else if(mid<l){
            update(rs,l,r,num);
        }
        else{
            update(ls,l,mid,num);
            update(rs,mid+1,r,num);
        }
    }
    
    int query(int t,int x){
        if(a[t].num||a[t].l==a[t].r){return a[t].num;}
        int mid=(a[t].l+a[t].r)>>1;
        if(x<=mid){return query(ls,x);}
        else{query(rs,x);}
    }
    
    int bit[maxn],n;
    int lowbit(int x){
        return x&(-x);
    }
    
    void update(int x,int num){
        while(x<maxn){
            bit[x]+=num;
            x+=lowbit(x);
        }
    }
    int query(int x){
        int ans=0;
        while(x>0){
            ans+=bit[x];
            x-=lowbit(x);
        }
        return ans;
    }
    int m;
    
    vector<pair<int,int> >g1[maxn];
    vector<int>g2[maxn];
    
    int main()
    {
        int T;
        scanf("%d",&T);
        while(T--){
            for(int i=0;i<maxn;i++){
                g1[i].clear();
                g2[i].clear();
            }
            scanf("%d%d",&n,&m);
            int x,l,k;
            build(1,1,n);
            for(int i=1;i<=m;i++){
                scanf("%d%d%d",&x,&l,&k);
                int L=max(1,x-k);
                int R=min(n,x+k);
                update(1,L,R,l);
                g1[l].push_back(make_pair(L,R));
            }
            for(int i=1;i<=n;i++){
                int k=query(1,i);
                g2[k].push_back(i);
            }
            int ans=0;
            for(int i=1;i<maxn;i++){
                int sz=g1[i].size();
                if(sz==0){continue;}
                for(int j=0;j<sz;j++){
                    update(g1[i][j].first,1);
                    update(g1[i][j].second+1,-1);
                }
                sz=g2[i].size();
                for(int j=0;j<sz;j++){
                    if(query(g2[i][j])>=2){ans++;}
                }
                sz=g1[i].size();
                for(int j=0;j<sz;j++){
                    update(g1[i][j].first,-1);
                    update(g1[i][j].second+1,1);
                }
            }
            printf("%d
    ",ans);
        }
        return 0;
    }
    View Code
  • 相关阅读:
    科大奥瑞大物实验-A类不确定度计算器 代码
    在手机和电脑间双向加密传输文件 —— Windows 安装 Kde Connect
    Leetcode 寻找两个有序数组的中位数
    树莓派3B安装 Arch Linux ARM
    从零开始编译安装 Extcalc
    Oracle, PostgreSQl, MySQL针对INSERT时可能唯一键重复的SQL
    如何从Oracle, MySql, PostgreSQL的PreparedStatement获得所执行的sql语句?
    PostgreSQL报错:当前事务被终止,命令被忽略,直到事务块结束
    PostgreSQL对GROUP BY子句使用常量的特殊限制
    一种用JDBC实现批量查询的巧妙方法
  • 原文地址:https://www.cnblogs.com/ZGQblogs/p/10662971.html
Copyright © 2011-2022 走看看