zoukankan      html  css  js  c++  java
  • cogs 181. [USACO Jan07] 最高的牛

    181. [USACO Jan07] 最高的牛

    ★★   输入文件:tallest.in   输出文件:tallest.out   简单对比
    时间限制:1 s   内存限制:32 MB

    FJ's N (1 ≤ N ≤ 10,000) cows conveniently indexed 1..N are standing in a line. Each cow has a positive integer height (which is a bit of secret). You are told only the height H (1 ≤ H ≤ 1,000,000) of the tallest cow along with the index I of that cow.

    FJ has made a list of R (0 ≤ R ≤ 10,000) lines of the form "cow 17 sees cow 34". This means that cow 34 is at least as tall as cow 17, and that every cow between 17 and 34 has a height that is strictly smaller than that of cow 17.

    For each cow from 1..N, determine its maximum possible height, such that all of the information given is still correct. It is guaranteed that it is possible to satisfy all the constraints.

     

    为了方便我们把FJ养的N头(1 ≤ N ≤ 10,000)奶牛从1号开始编号,一直编到N号,并且让他们站成一列。每头牛都有一个正整数用来描述她的身高(有些牛不愿意说,她们的身高保密)。你只知道这些牛中最高的那一头的身高是H,她的编号是第I号。

    FJ写了一张单子,上面有R个陈述句,大概是”第17号牛可以看见第34号牛”这种。这意味着第34号牛最起码和第17号牛一样高。而且17号牛和34号牛之间的牛得身高都严格的小于min(H[17],H[34])。

    从第1号牛到第N号牛,求她们可能拥有的最大身高,所给出的所有信息都是正确的。这可以保证满足所有条件。

     

    Input

    • Line 1: Four space-separated integers: N, I, H and R
    • Lines 2..R + 1: Two distinct space-separated integers A and B (1 ≤ A, B ≤ N), indicating that cow A can see cow B.

     

    输入:

    第1行:四个由空格分开的整数,N,I,H和R。

    第2..R+1行:两个由空格分开的整数A和B(1 ≤ A, B ≤ N),表示第A号牛可以看到第B号牛。

     

    Output

    • Lines 1..N: Line i contains the maximum possible height of cow i.

     

    输出:

    第1..N行:第i行包括第i号牛可能拥有的最大身高。

     

    Sample Input

    9 3 5 5
    1 3
    5 3
    4 3
    3 7
    9 8
    

    Sample Output

    5
    4
    5
    3
    4
    4
    5
    5
    5
    

    Input Details

    There are 9 cows, and the 3rd is the tallest with height 5.

     

    输入细节:

    由9头奶牛,第三头奶牛最高,身高是5.

    译byKZFFFFFFFF

     思路:线段树。

    #include<map>
    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #define MAXN 10000
    using namespace std;
    map<int,int>ma[MAXN];
    struct nond{
        int l,r,flag;
    }tree[MAXN*4];
    long long n,I,H,R;
    void build(int now,int l,int r){
        tree[now].l=l;tree[now].flag=0;
        tree[now].r=r;
        if(tree[now].l==tree[now].r)
            return ;
        long long mid=(tree[now].l+tree[now].r)/2;
        build(now*2,l,mid);
        build(now*2+1,mid+1,r);
    }
    void down(int now){
        tree[now*2].flag+=tree[now].flag;
        tree[now*2+1].flag+=tree[now].flag;
        tree[now].flag=0;
    }
    void change(int now,int l,int r){
        if(tree[now].l==l&&tree[now].r==r){
            tree[now].flag+=1;
            return ;
        }
        if(tree[now].flag)    down(now);
        int mid=(tree[now].l+tree[now].r)/2;
        if(r<=mid)    change(now*2,l,r);
        else if(l>mid)    change(now*2+1,l,r);
        else{
            change(now*2,l,mid);
            change(now*2+1,mid+1,r);
        }
    }
    int query(int now,int x){
        if(tree[now].l==tree[now].r)
            return tree[now].flag;
        if(tree[now].flag)    down(now);
        int mid=(tree[now].l+tree[now].r)/2;
        if(x<=mid)    return query(now*2,x);
        else if(x>mid)    return query(now*2+1,x);
    }
    int main(){
        //freopen("tallest.in","r",stdin);
        //freopen("tallest.out","w",stdout);
        while(scanf("%lld%lld%lld%lld",&n,&I,&H,&R)!=EOF){
            build(1,1,n);
            for(int i=1;i<=R;i++){
                long long a,b;
                scanf("%lld%lld",&a,&b);
                if(a>b)    swap(a,b);
                if(ma[a][b])    continue;
                ma[a][b]=1;
                if(a+1==b)    continue;
                change(1,a+1,b-1);
            }
            for(long long i=1;i<=n;i++)
                cout<<H-query(1,i)<<endl;
        }
    }
    一直调不对的20分代码

    AC代码

    #include<iostream>  
    #include<cstdio>  
    #include<cstring>  
    #include<algorithm>  
    #include<limits.h>  
    using namespace std;  
    const int maxn=10000+100;  
    int LL[maxn],RR[maxn];  
    long long N,H,R,I;  
    long long add[maxn<<2],ans[maxn];  
    struct node{  
        int l,r;  
        int sum;  
    }t[maxn<<2];  
    void pushdown(int rs)//向下更新lazy积累的值  
    {  
        if(add[rs])  
        {  
            add[rs<<1]+=add[rs];  
            add[rs<<1|1]+=add[rs];  
            add[rs]=0;  
        }  
    }  
    void build(int rs,int l,int r)  
    {  
        t[rs].l=l;  
        t[rs].r=r;  
        add[rs]=0;  
        if(l==r)  
        { 
            t[rs].sum=H;  
            return ;  
        }  
        int mid=(l+r)>>1;  
        build(rs<<1,l,mid);  
        build(rs<<1|1,mid+1,r);  
    }  
    void update(int l,int r,int rs)//更新操作  
    {  
        if(t[rs].l>=l&&t[rs].r<=r)  
        {  
            add[rs]+=1;  
            return ;  
        }  
        pushdown(rs);
        int mid=(t[rs].l+t[rs].r)>>1;  
        if(l<=mid)   update(l,r,rs<<1);  
        if(r>mid)  update(l,r,rs<<1|1);  
    }  
    int query(int k,int rs)  
    {  
        if(t[rs].l==t[rs].r)  
        {  
            return t[rs].sum-=add[rs];  
        }  
        pushdown(rs);  
        int mid=(t[rs].l+t[rs].r)>>1;  
        if(k<=mid)  return query(k,rs<<1);  
        else  return query(k,rs<<1|1);  
    }  
    int main()  
    {  
        freopen("tallest.in","r",stdin);
        freopen("tallest.out","w",stdout);
        int u,v;  
       scanf("%I64d%I64d%I64d%I64d",&N,&I,&H,&R);
            build(1,1,N);  
            int k=0;  
            while(R--)  
            {  
                scanf("%d%d",&u,&v);  
                if(u>v)  swap(u,v);  
                int flag=1;  
                for(int i=0;i<k;i++)//判断重边,在poj做题一定要防这东西  
                {  
                    if(u==LL[i]&&v==RR[i])  
                    {  
                        flag=0;  
                        break;  
                    }  
                }  
                if(!flag)  
                    continue;  
                LL[k]=u;RR[k]=v;  
                k++;  
                if(v-u==1)//相邻的话就不用更新了  
                    continue;  
      
                update(u+1,v-1,1);//注意是开区间的值更新  
            }  
            for(int i=1;i<=N;i++)  
                ans[i]=query(i,1);  
            for(int i=1;i<=N;i++)  
                printf("%I64d
    ",ans[i]);  
        return 0;  
    }  
    细雨斜风作晓寒。淡烟疏柳媚晴滩。入淮清洛渐漫漫。 雪沫乳花浮午盏,蓼茸蒿笋试春盘。人间有味是清欢。
  • 相关阅读:
    关于在windows10中的vmware9.0里面安装的ubuntukylin15.04和windows共享目录的一些反思
    关于最近工程的一些心得
    关于springMVC中component-scan的问题以及springmvc.xml整理
    初学node.js有感三
    初学node.js有感二
    初学node.js有感一
    编译原理——算符优先分析文法(附源代码)
    数据结构与算法系列研究九——排序算法的一些探讨
    LeetCode: Same Tree
    LeetCode: Symmetric Tree
  • 原文地址:https://www.cnblogs.com/cangT-Tlan/p/8151173.html
Copyright © 2011-2022 走看看