zoukankan      html  css  js  c++  java
  • [nowcoder5667G]Greater and Greater

    令$f[i][j]$表示前i个数的后j位能否匹配b的前j位,有转移$f[i][j]=f[i-1][j-1] &  [b_{j}le a_{i}]$
    将$g[i][j]=[b_{j}le a_{i}]$看成一个i为位数的二进制数,即$g[i]=sum_{j=1}^{m}[b_{j}le a_{i}]cdot 2^{j}$,$f[i]$同理,那么就有$f[i]=f[i-1] & g[i]$
    考虑对于$g$预处理,由于这个值仅和最小的大于$a_{i}$的$b_{j}$有关,因此将b排序后求出每一个$b_{i}$所对应的g,在其中二分即可求出$a_{i}$所对应的g
    但这样的空间复杂度打到了$o(frac{m(2n+m)}{8})$,考虑将f滚动、求g的二分放到f转移时进行,空间降为$o(frac{m^{2}}{8})$,可以通过
     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 #define N 150005
     4 struct ji{
     5     int k,id;
     6     bool operator < (const ji &a)const{
     7         return (k<a.k)||(k==a.k)&&(id<a.id);
     8     }
     9 }a[N];
    10 int n,m,ans,b[N];
    11 bitset<40005>o,s,g[40005];
    12 void write(bitset<40005> o){
    13     for(int i=1;i<=m;i++){
    14         int x=o[i];
    15         printf("%d ",x);
    16     }
    17     printf("
    ");
    18 }
    19 int main(){
    20     scanf("%d%d",&n,&m);
    21     for(int i=1;i<=n;i++)scanf("%d",&b[i]);
    22     for(int i=1;i<=m;i++){
    23         scanf("%d",&a[i].k);
    24         a[i].id=i;
    25     }
    26     sort(a+1,a+m+1);
    27     g[1][0]=1;
    28     for(int i=1,j=1;i<=m;i=j){
    29         while (a[i].k==a[j].k)j++;
    30         g[j]=g[i];
    31         for(int k=i;k<j;k++)g[j][a[k].id]=1;
    32     }
    33     o[0]=s[0]=1;
    34     for(int i=1;i<=n;i++){
    35         s=(((s<<1)|o)&g[upper_bound(a+1,a+m+1,ji{b[i],m+1})-a]);
    36         if (s[m]==1)ans++;
    37     }
    38     printf("%d",ans);
    39 }
    View Code
  • 相关阅读:
    unistd.h文件
    error C3861: “getpid”: 找不到标识符
    #include <unistd.h> 的作用
    VS2013 配置pthread
    VS2008和VC6.0下使用pthread.h头文件
    文件下载之断点续传(客户端与服务端的实现)
    C++ 判断进程是否存在
    C/C++遍历进程和进程ID的小工具
    linux --> 文件系统十问
    网络通信 --> CRC校验
  • 原文地址:https://www.cnblogs.com/PYWBKTDA/p/13334474.html
Copyright © 2011-2022 走看看