zoukankan      html  css  js  c++  java
  • BZOJ 2038 小Z的袜子 莫队算法

    题解:
    区间总的方案数是可以算的,只要求相同的颜色的方案数即可。(数学中讲的古典概型??)

    我不知道我写的是不是莫队算法,时间还是很快的。。

    话说,这题稍微优化的暴力也能过。

    看了别人的介绍莫队算法的文章没有看太懂,也不知道这个神奇的复杂度是怎么证明的。。。

    我大致是这样做的:

    1、分块

    2、把所有询问左端点排序

    3、对于左端点在同一块内的询问按右端点排序,然后分三种情况统计。

    传说中这样复杂度是nsqrt(n)的,但是我怎么觉得这个和我的暴力差不多。。。。

    莫名其妙跑的这么快。。。

    View Code
      1 #include <iostream>
      2 #include <cstring>
      3 #include <cstdio>
      4 #include <cstdlib>
      5 #include <algorithm>
      6 #include <cmath>
      7 
      8 #define N 55555
      9 
     10 using namespace std;
     11 
     12 struct Q
     13 {
     14     long long l,r,id;
     15 }q[N];
     16 
     17 struct ANS
     18 {
     19     long long a,b;
     20     void in(long long x,long long y) {a=x,b=y;}
     21 }ans[N];
     22 
     23 long long col[N],n,m,gs[N];
     24 long long lt[N],rt[N],len,tot;
     25 
     26 inline bool cmpl(const Q &a,const Q &b)
     27 {
     28     return a.l<b.l;
     29 }
     30 
     31 inline bool cmpr(const Q &a,const Q &b)
     32 {
     33     return a.r<b.r;
     34 }
     35 
     36 inline void read()
     37 {
     38     scanf("%lld%d",&n,&m);
     39     for(long long i=1;i<=n;i++) scanf("%lld",&col[i]);
     40     for(long long i=1;i<=m;i++)
     41     {
     42         scanf("%lld%d",&q[i].l,&q[i].r);
     43         q[i].id=i;
     44     }
     45     len=(long long)sqrt(1.0*n);
     46     tot=n/len;
     47     for(long long i=1;i<=tot;i++) lt[i]=rt[i-1]+1,rt[i]=rt[i-1]+len;
     48     if(rt[tot]!=n) lt[tot+1]=rt[tot]+1,rt[tot+1]=n,tot++;
     49 }
     50 
     51 inline long long gcd(long long x,long long y)
     52 {
     53     long long ys;
     54     while(y)
     55     {
     56         ys=x%y;
     57         x=y; y=ys;
     58     }
     59     return x;
     60 }
     61 
     62 inline void getans(long long x,long long ml)
     63 {
     64     long long sum=(q[x].r-q[x].l)*(q[x].r-q[x].l+1)/2;
     65     long long mx=gcd(ml,sum);
     66     if(!mx) ans[q[x].id].in(0,1);
     67     else ans[q[x].id].in(ml/mx,sum/mx);
     68 }
     69 
     70 inline void go()
     71 {
     72     sort(q+1,q+m+1,cmpl);
     73     long long s=1,t=1;
     74     for(long long i=1,ml=0;i<=tot;i++,ml=0)
     75     {
     76         memset(gs,0,sizeof gs);
     77         while(s<=m&&q[s].l<lt[i]) s++;
     78         while(t<=m&&q[t].l<=rt[i]) t++;
     79         if(s>m||q[s].l>rt[i]) continue;
     80         sort(q+s,q+t,cmpr);
     81         for(long long j=q[s].l;j<=q[s].r;j++) ml+=gs[col[j]],gs[col[j]]++;
     82         getans(s,ml);
     83         for(long long j=s+1;j<t;j++)
     84         {
     85             if(q[j].l<q[j-1].l)
     86             {
     87                 for(long long k=q[j].l;k<q[j-1].l;k++) ml+=gs[col[k]],gs[col[k]]++;
     88                 for(long long k=q[j-1].r+1;k<=q[j].r;k++) ml+=gs[col[k]],gs[col[k]]++;
     89             }
     90             else if(q[j].l>q[j-1].r)
     91             {
     92                 for(long long k=q[j-1].l;k<=q[j-1].r;k++) gs[col[k]]--;
     93                 ml=0;
     94                 for(long long k=q[j].l;k<=q[j].r;k++) ml+=gs[col[k]],gs[col[k]]++;
     95             }
     96             else
     97             {
     98                 for(long long k=q[j-1].l;k<q[j].l;k++) gs[col[k]]--,ml-=gs[col[k]];
     99                 for(long long k=q[j-1].r+1;k<=q[j].r;k++) ml+=gs[col[k]],gs[col[k]]++;
    100             }
    101             getans(j,ml);
    102         }
    103     }
    104     for(long long i=1;i<=m;i++) printf("%lld/%lld\n",ans[i].a,ans[i].b);
    105 }
    106 
    107 int main()
    108 {
    109     read(),go();
    110     return 0;
    111 }

    这个莫队算法是处理区间无修改询问的通用算法??

  • 相关阅读:
    BZOJ 3205 [Apio2013]机器人 ——斯坦纳树
    BZOJ 3782 上学路线 ——动态规划 Lucas定理 中国剩余定理
    HDU 1423 Greatest Common Increasing Subsequence ——动态规划
    BZOJ 3309 DZY Loves Math ——莫比乌斯反演
    POJ 1038 Bugs Integrated, Inc. ——状压DP
    POJ 3693 Maximum repetition substring ——后缀数组
    POJ 2699 The Maximum Number of Strong Kings ——网络流
    POJ 2396 Budget ——有上下界的网络流
    BZOJ 4650 [Noi2016]优秀的拆分 ——后缀数组
    源码安装python
  • 原文地址:https://www.cnblogs.com/proverbs/p/2941890.html
Copyright © 2011-2022 走看看