• Genius ACM


    题解:

    发现匹配一定会选最大和最小匹配,确定左右端点之后nlogn排序后算

    比较容易想到二分 最坏情况每次1个 $n^2*(logn)^2$

    没错暴力的最差复杂度是$n^2*logn$的

    发现长度与次数相关

    二分改成倍增 $n(logn)^2$

    然后大概常数好就过了吧

    倍增的时候我们可以把排序看成一段有序的+一段无序的

    可以把无序的先排序再和有序的归并

    时间复杂度nlogn

    代码:

    #include <bits/stdc++.h> 
    using namespace std;
    #define rint register int
    #define IL inline
    #define rep(i,h,t) for (rint i=h;i<=t;i++)
    #define dep(i,t,h) for (rint i=t;i>=h;i--)
    #define ll long long
    char ss[1<<24],*A=ss,*B=ss;
    IL char gc()
    {
        return A==B&&(B=(A=ss)+fread(ss,1,1<<24,stdin),A==B)?EOF:*A++; 
    }
    template<class T>void read(T &x)
    {
        rint f=1,c; while (c=gc(),c<48||c>57) if (c=='-') f=-1; x=(c^48); 
        while (c=gc(),c>47&&c<58) x=(x<<3)+(x<<1)+(c^48); x*=f;     
    }
    const int N=6e5;
    int a[N],b[N],n,m,c[N],d[N],e[N],len;
    ll k;
    IL bool check(rint x,rint y)
    {
        rint len=y-x+1;
        rep(i,x,y) b[i-x+1]=a[i];
        sort(b+1,b+len+1);
        rint tmp=len/2;
        ll ans=0;
        rep(i,1,m)
        {
            if (i>tmp) break;
            ans+=1ll*(b[i]-b[len-i+1])*(b[i]-b[len-i+1]);
        }
        if (ans<=k) return(1); else return(0);
    }
    IL bool check(rint x,rint y,rint h2,rint t2)
    {
        rint len2=t2-h2+1;
        rep(i,h2,t2) c[i-h2+1]=a[i];
        sort(c+1,c+len2+1);
        int h1=1,t1=len; h2=1,t2=len2;
        int cnt=0;
        while (h2<=t2&&h1<=t1)
        {
            if (b[h1]<c[h2]) d[++cnt]=b[h1],h1++;
            else d[++cnt]=c[h2],h2++;
        }
        while (h1<=t1) d[++cnt]=b[h1],h1++;
        while (h2<=t2) d[++cnt]=c[h2],h2++;
        rep(i,1,len) e[i]=b[i];
        rep(i,1,cnt) b[i]=d[i];
        rint tmp2=len; len=cnt;
        rint tmp=len/2;
        ll ans=0;
        rep(i,1,m)
        {
            if (i>tmp) break;
            ans+=1ll*(b[i]-b[len-i+1])*(b[i]-b[len-i+1]);
        }
        if (ans<=k) return(1); else
        {
          len=tmp2; 
          rep(i,1,len) b[i]=e[i];
          return(0);
        }
    }
    IL int js(register int x)
    {
        register int y=x;
        register int i=1;
        register int lst=x-1;
        while (i>=0)
        {
          for (i=0;i<=19;i++)
          { 
            if (!check(y,x+(1<<i)-1,lst+1,x+(1<<i)-1)) break;
            lst=x+(1<<i)-1;
          }
          i--;
          x=x+(1<<i)-1;
          i--;
          if (x>n) break;
        }
        return x;
    }
    int main()
    {
        freopen("geniusacm.in","r",stdin);
        freopen("geniusacm.out","w",stdout);
        int T;
        read(T);
        rep(tt,1,T)
        {
            read(n); read(m); read(k);
            rep(i,1,n) read(a[i]);
            int now=1,cnt=0;
            while (now<=n)
            {
                len=0;
                now=js(now)+1;
                cnt++;
            }
            cout<<cnt<<endl;
        }
        return 0; 
    } 
  • 相关阅读:
    java静态代码分析工具infer
    Go的安装和使用/卸载/升级、安装指定版本
    ldap服务器OpenLDAP安装使用
    python2 和 python3兼容写法
    ldap客户端以及jenkins的配置
    mac下java的安装和升级以及相关环境设置
    常见高危安全漏洞
    XFS: Cross Frame Script (跨框架脚本) 攻击。
    WEB渗透测试之三大漏扫神器
    编写自己的Acunetix WVS漏洞扫描脚本详细教程
  • 原文地址:https://www.cnblogs.com/yinwuxiao/p/9865790.html
Copyright © 2020-2023  润新知