zoukankan      html  css  js  c++  java
  • 数据结构(脑洞题,BIT):COGS 2394. 比赛

    比赛

    时间限制:1 s   内存限制:256 MB

    【题目描述】

       n(n≤100000)个人编号为0到n-1,每人都有一个能力值,大小在0到n-1之间,各不相同,他们之间有c场比赛,每场比赛指定一个区间 [l,r],当前第l个到第r个中能力值最大的获胜,其他的都被淘汰,不再出现在候选之列,现在你是n个人中的一个,也要参加这比赛,但你可以选择已经排 好的n-1人之间的n个位置中的一个进行插入,使得自己赢的场数最多,输出最小的位置。

    【输入格式】

       第一行三个数n c k,k是你的能力值。

       接下来n-1行表示前n-1个人的能力值。

       最后c行表示比赛,保证比赛合法。

    【输出格式】

       一行即答案。

    【样例输入】

    5 3 3

    1

    0

    2

    4

    1 3

    0 1

    0 1

    【样例输出】

    1

      这道题,发现对于一个比赛,求出其实际上对应的人分别是哪些,假想每个人自己一个人比赛一次,再考虑对于比赛建树,一个A节点是另一个节点B的子节点仅当A的最强者参加了比赛B,维护胜利者的能力值。假设要参加某场比赛,那么发现这场比赛中最后一个人被挤出去了,所以对于树中节点不统计最后那个人的信息,但在整合子树时考虑。

     1 #include <iostream>
     2 #include <cstring>
     3 #include <cstdio>
     4 using namespace std;
     5 const int maxn=200010;
     6 int bit[maxn],N,fa[maxn];
     7 int a[maxn],Max[maxn];
     8 int ID[maxn],dp[maxn];
     9 int L[maxn],R[maxn];
    10 int n,c,k;
    11 
    12 void Add(int x,int d){
    13     while(x<=N){
    14         bit[x]+=d;
    15         x+=x&(-x);
    16     }
    17 }
    18 
    19 int Pos(int k){
    20     int p=0;
    21     for(int i=N;i;i>>=1)
    22         if(bit[p+(i>>1)]<k)
    23             k-=bit[p+=i>>1];
    24     return p+1;
    25 }
    26 
    27 int main(){
    28     freopen("competition.in","r",stdin);
    29     freopen("competition.out","w",stdout);
    30     scanf("%d%d%d",&n,&c,&k);
    31     for(N=1;N<=n;N<<=1);
    32     for(int i=1;i<n;i++){
    33         scanf("%d",&a[i]);
    34         Add(i,1);ID[i]=i;
    35         L[i]=R[i]=i;
    36     }Add(n+1,1);
    37     for(int i=1,l,r;i<=c;i++){
    38         scanf("%d%d",&l,&r);l++,r++;
    39         L[n+i]=Pos(l);R[n+i]=Pos(r+1)-1;
    40         for(int j=l;j<=r;j++){
    41             int x=ID[Pos(j)];fa[x]=n+i;
    42             Max[n+i]=max(Max[n+i],Max[x]);
    43             if(j!=r)Max[n+i]=max(Max[n+i],a[R[x]]);
    44         }
    45         ID[L[n+i]]=n+i;
    46         for(int j=r;j>l;j--)
    47             Add(Pos(j),-1);
    48     }
    49     
    50     for(int i=c;i>=1;i--)
    51         dp[n+i]=Max[n+i]<k?dp[fa[n+i]]+1:0;
    52     
    53     int M=0,p=1;
    54     for(int i=1;i<=n;i++)
    55         if(dp[fa[i]]>M)
    56             M=dp[fa[i]],p=i;
    57     printf("%d
    ",p-1);        
    58     return 0;
    59 }
  • 相关阅读:
    ThinkPHP 3.2.2 实现持久登录 ( 记住我 )
    Java实现 LeetCode 20 有效的括号
    Java实现 LeetCode 20 有效的括号
    Java实现 LeetCode 19删除链表的倒数第N个节点
    Java实现 LeetCode 19删除链表的倒数第N个节点
    Java实现 LeetCode 19删除链表的倒数第N个节点
    Java实现 LeetCode 18 四数之和
    Java实现 LeetCode 18 四数之和
    Java实现 LeetCode 18 四数之和
    Java实现 LeetCode 17 电话号码的字母组合
  • 原文地址:https://www.cnblogs.com/TenderRun/p/5688384.html
Copyright © 2011-2022 走看看