• 主席树||可持久化线段树||BZOJ 3524: [Poi2014]Couriers||BZOJ 2223: [Coci 2009]PATULJCI||Luogu P3567 [POI2014]KUR-Couriers


    题目:[POI2014]KUR-Couriers

    题解:

    要求出现次数大于(R-L+1)/2的数,这样的数最多只有一个。我们对序列做主席树,每个节点记录出现的次数和(sum)。(这里忽略版本差值问题)对于一个节点,如果左儿子的sum小于等于(R-L+1)/2,则答案不可能在左儿子中;右儿子同理。然后对有可能的儿子递归寻找答案,如果左右儿子都不可能,则不存在答案。

    代码:

    BZOJ 3524:

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<iostream>
     4 using namespace std;
     5 inline int rd(){
     6     int x=0,f=1;char c=getchar();
     7     while(c<'0'||c>'9'){if(c=='-')f=-1; c=getchar();}
     8     while(c>='0'&&c<='9'){x=x*10+c-'0'; c=getchar();}
     9     return f*x;
    10 }
    11 const int maxn=(5e5)+50,maxm=maxn;
    12 int N,M,L,R,root[maxn],num_treenode=0,A;
    13 struct Tree{
    14     int l,r,sum,ls,rs;
    15 }t[(maxn<<2)+maxn*20];
    16 inline void Build(int x,int l,int r){
    17     t[x].l=l;t[x].r=r;int mid=(l+r)>>1;
    18     if(l==r)return;
    19     Build(t[x].ls=++num_treenode,l,mid);Build(t[x].rs=++num_treenode,mid+1,r);
    20     return;
    21 }
    22 inline void Update(int u,int x,int q){
    23     int l=t[u].l,r=t[u].r,mid=(l+r)>>1;
    24     t[x].l=l;t[x].r=r;
    25     if(l==r&&l==q){
    26         t[x].sum=t[u].sum+1;
    27         return;
    28     }
    29     if(q<=mid){
    30         t[x].rs=t[u].rs;
    31         Update(t[u].ls,t[x].ls=++num_treenode,q);
    32     }
    33     else {
    34         t[x].ls=t[u].ls;
    35         Update(t[u].rs,t[x].rs=++num_treenode,q);
    36     }
    37     t[x].sum=t[t[x].ls].sum+t[t[x].rs].sum;
    38     return;
    39 }
    40 inline int Query(int u,int x,int z){
    41     int l=t[u].l,r=t[u].r;
    42     if(l==r)return l;
    43     if(t[t[x].ls].sum-t[t[u].ls].sum>z)return Query(t[u].ls,t[x].ls,z);
    44     if(t[t[x].rs].sum-t[t[u].rs].sum>z)return Query(t[u].rs,t[x].rs,z);
    45     return 0;
    46 }
    47 int main(){
    48     N=rd();M=rd();
    49     Build(root[0]=++num_treenode,1,N);
    50     for(int i=1;i<=N;i++){
    51         A=rd();
    52         Update(root[i-1],root[i]=++num_treenode,A);
    53     }
    54     while(M--){
    55         L=rd();R=rd();
    56         printf("%d
    ",Query(root[L-1],root[R],(R-L+1)>>1));
    57     }
    58     return 0;
    59 }

    BZOJ 2223:

    这道题的样例很坑,我整理了一下:

    10 3
    1 2 1 2 1 2 3 2 3 3
    8
    1 2
    1 3
    1 4
    1 5
    2 5
    2 6
    6 9
    7 10
     1 #include<cstdio>
     2 #include<cstring>
     3 #include<iostream>
     4 using namespace std;
     5 inline int rd(){
     6     int x=0,f=1;char c=getchar();
     7     while(c<'0'||c>'9'){if(c=='-')f=-1; c=getchar();}
     8     while(c>='0'&&c<='9'){x=x*10+c-'0'; c=getchar();}
     9     return f*x;
    10 }
    11 const int maxn=(3e5)+50,maxm=10050;
    12 int N,M,L,R,root[maxn],num_treenode=0,A,ans,Lim;
    13 struct Tree{
    14     int l,r,sum,ls,rs;
    15 }t[(maxn<<2)+maxn*20];
    16 inline void Build(int x,int l,int r){
    17     t[x].l=l;t[x].r=r;int mid=(l+r)>>1;
    18     if(l==r)return;
    19     Build(t[x].ls=++num_treenode,l,mid);Build(t[x].rs=++num_treenode,mid+1,r);
    20     return;
    21 }
    22 inline void Update(int u,int x,int q){
    23     int l=t[u].l,r=t[u].r,mid=(l+r)>>1;
    24     t[x].l=l;t[x].r=r;
    25     if(l==r&&l==q){
    26         t[x].sum=t[u].sum+1;
    27         return;
    28     }
    29     if(q<=mid){
    30         t[x].rs=t[u].rs;
    31         Update(t[u].ls,t[x].ls=++num_treenode,q);
    32     }
    33     else {
    34         t[x].ls=t[u].ls;
    35         Update(t[u].rs,t[x].rs=++num_treenode,q);
    36     }
    37     t[x].sum=t[t[x].ls].sum+t[t[x].rs].sum;
    38     return;
    39 }
    40 inline int Query(int u,int x,int z){
    41     int l=t[u].l,r=t[u].r;
    42     if(l==r)return l;
    43     if(t[t[x].ls].sum-t[t[u].ls].sum>z)return Query(t[u].ls,t[x].ls,z);
    44     if(t[t[x].rs].sum-t[t[u].rs].sum>z)return Query(t[u].rs,t[x].rs,z);
    45     return 0;
    46 }
    47 int main(){
    48     N=rd();Lim=rd();
    49     Build(root[0]=++num_treenode,1,Lim);
    50     for(int i=1;i<=N;i++){
    51         A=rd();
    52         Update(root[i-1],root[i]=++num_treenode,A);
    53     }
    54     M=rd();
    55     while(M--){
    56         L=rd();R=rd();
    57         if(L>R){
    58             printf("no
    ");
    59             continue;
    60         }
    61         ans=Query(root[L-1],root[R],(R-L+1)>>1);
    62         if(ans==0)printf("no
    ");else printf("yes %d
    ",ans);
    63     }
    64     return 0;
    65 }

    By:AlenaNuna

  • 相关阅读:
    Paths on a Grid
    Three Kingdoms(优先队列+bfs)
    Factstone Benchmark(数学)
    C. Searching for Graph(cf)
    B. Trees in a Row(cf)
    String Successor(模拟)
    乘积最大的分解(数学)
    Kindergarten Election
    In 7-bit
    Friends
  • 原文地址:https://www.cnblogs.com/AlenaNuna/p/10397419.html
Copyright © 2020-2023  润新知