• E. Two Teams(线段树+链表)


     题目链接:

    https://codeforces.com/problemset/problem/1154/E

    题目大意:

    给你n个人和间隔k,两个教练从里面选人。每一次教练选出这个区间里面权值最大的那个学生,然后这个学生往左k个,往右k个,都是这个教练的学生。选完的学生会退出,然后剩余的学生自动补齐。然后问你每一个学生的教练是谁?

    具体思路:

    一开始没有注意到时自动补齐的,打了一个线段树区间覆盖,wa4

    对于这个自动补全,我们可以建立一个链表的形式,保存这个点前面的学生是谁,后面的学生是谁

    然后每一次寻找这个区间里面最大的学生编号是哪个,然后这个学生往左往右k个都是当前的教练学生。TLE在37

    继续改进,发现有更新操作,也就是说我们可以通过直接判断tree[1]的值就知道当前这个区间里面最大的权值是哪个。然后打一个映射就知道这个学生的编号了,注意指针的跳动。

    AC代码:

      1 #include<bits/stdc++.h>
      2 using namespace std;
      3 # define ll long long
      4 # define inf 0x3f3f3f3f
      5 # define lson l,mid,rt<<1
      6 # define rson mid+1,r,rt<<1|1
      7 const int maxn = 2e5+100;
      8 int pre[maxn],nex[maxn];
      9 int a[maxn];
     10 int tree[maxn<<2];
     11 int lazy[maxn<<2];
     12 void down(int rt)
     13 {
     14     if(lazy[rt])
     15     {
     16         tree[rt<<1]=0;
     17         tree[rt<<1|1]=0;
     18         lazy[rt<<1]=1;
     19         lazy[rt<<1|1]=1;
     20         lazy[rt]=0;
     21     }
     22 }
     23 void up(int rt)
     24 {
     25     tree[rt]=max(tree[rt<<1],tree[rt<<1|1]);
     26 }
     27 void build(int l,int r,int rt)
     28 {
     29     if(l==r)
     30     {
     31         tree[rt]=a[l];
     32         return ;
     33     }
     34     int mid=l+r>>1;
     35     build(lson);
     36     build(rson);
     37     up(rt);
     38 }
     39 int ans[maxn];
     40 int maxx,id;
     41 int pos[maxn];
     42 //void  ask(int l,int r,int rt)
     43 //{
     44 //    if(tree[rt]<maxx)
     45 //        return ;
     46 //    if(tree[rt]>maxx)
     47 //    {
     48 //        maxx=tree[rt];
     49 //    }
     50 //    int mid=l+r>>1;
     51 //    down(rt);
     52 //    if(l<=mid)
     53 //    ask(lson);
     54 //    if(r>mid)
     55 //    ask(rson);
     56 //    up(rt);
     57 //}
     58 void update(int l,int r,int rt,int L,int R)
     59 {
     60     if(L<=l&&R>=r)
     61     {
     62         lazy[rt]=1;
     63         tree[rt]=0;
     64         return ;
     65     }
     66     down(rt);
     67     int mid=l+r>>1;
     68     if(L<=mid)
     69         update(lson,L,R);
     70     if(R>mid)
     71         update(rson,L,R);
     72     up(rt);
     73 }
     74 int main()
     75 {
     76     int n,k;
     77     scanf("%d %d",&n,&k);
     78     for(int i=1; i<=n; i++)
     79     {
     80         scanf("%d",&a[i]);
     81         pre[i]=i-1;
     82         nex[i]=i+1;
     83         pos[a[i]]=i;
     84     //cout<<1<<endl;
     85     }
     86     build(1,n,1);
     87     int flag=1,type=1;
     88     while(flag)
     89     {
     90         maxx=tree[1];
     91 //        ask(1,n,1);
     92         if(!maxx)
     93             break;
     94         id= pos[maxx];
     95         ans[id]=type;
     96         //  cout<<id<<" ";
     97         int tmp_l=id;
     98         for(int i=1; i<=k; i++)
     99         {
    100             if(pre[tmp_l]==0)
    101                 break;
    102             ans[pre[tmp_l]]=type;
    103             //  cout<<pre[tmp_l]<<" ";
    104             tmp_l=pre[tmp_l];
    105         }
    106         int  tmp_r=id;
    107         for(int i=1; i<=k; i++)
    108         {
    109             if(nex[tmp_r]==n+1)
    110                 break;
    111             ans[nex[tmp_r]]=type;
    112             //    cout<<pre[tmp_l]<<" ";
    113             tmp_r=nex[tmp_r];
    114         }
    115         update(1,n,1,tmp_l,tmp_r);
    116         int tmp1=nex[tmp_r];
    117         int tmp2=pre[tmp_l];
    118         pre[tmp1]=tmp2;
    119         nex[tmp2]=tmp1;
    120         type=(type==1?2:1);
    121     }
    122     for(int i=1; i<=n; i++)
    123     {
    124         printf("%d",ans[i]);
    125     }
    126     printf("
    ");
    127     return 0;
    128 }
  • 相关阅读:
    HDU6397
    容斥原理推导错排通项公式
    重复排列的证明
    圆排列证明
    rock-paper-scissors
    The more, The Better
    趁着情人节写点东西
    分层图最短路问题
    背包问题是否装满问题
    Python面向对象编程扑克牌发牌程序,另含大量Python代码!
  • 原文地址:https://www.cnblogs.com/letlifestop/p/10948751.html
Copyright © 2020-2023  润新知