• 【BZOJ2038】小Z的袜子(莫队)


    题意:

    给定n个数a1, a2…… an与m个询问(L,R)。对于每个询问,从aL, aL+1…… aR这R-L+1个数中随机取出两个数,求这两个数相同的概率。

    数据范围:1<=n,m,ai<=50000

    思路:

    以下是原话:

    平方运算的存在是线段树无法打破的坚冰!

    只有询问,没有修改! 可以任意的顺序求解询问!

     考虑两个位置关系任意的区间[L1,R1]与[L2,R2]

    已有前者的信息,要得到后者的信息只需插入或删除L1与L2间的数和R1与R2间的数

    若L1<L2则删除[L1,L2-1]内的数, 否则插入[L2,L1-1]内的数;

    若R1<R2则插入[R1+1,R2]内的数, 否则删除[R2+1,R1]内的数;

    无论何种情况,所需操作数均为 |L1 - L2| + |R1 - R2|

    将m个区间重新排列,最小化:

    定义(L0,R0) = (1,0)

    分块,将询问以左端点所在块的编号为第一关键字,右端点大小为第二关键字排序,依次计算保证

    时间复杂度O(N^1.5)

    复杂度分析是这样的:
    1、i与i+1在同一块内,r单调递增,所以r是O(n)的。由于有n^0.5块,所以这一部分时间复杂度是n^1.5。
    2、i与i+1跨越一块,r最多变化n,由于有n^0.5块,所以这一部分时间复杂度是n^1.5
    3、i与i+1在同一块内时l变化不超过n^0.5,跨越一块也不会超过n^0.5,忽略*2。由于有m次询问(和n同级),所以时间复杂度是n^1.5
    于是就是O(n^1.5)了

      1 type arr=record
      2           l,r,c,t:longint;
      3          end;
      4 var s:array[0..50000]of int64;
      5     ans:array[1..50000,1..2]of int64;
      6     q:array[1..50000]of arr;
      7     c,a:array[1..50000]of longint;
      8     n,m,i,kuai:longint;
      9     tmp:int64;
     10 
     11 procedure swap(var x,y:arr);
     12 var t:arr;
     13 begin
     14  t:=x; x:=y; y:=t;
     15 end;
     16 
     17 procedure qsort(l,r:longint);
     18 var i,j,mid1,mid2:longint;
     19 begin
     20  i:=l; j:=r; mid1:=q[(l+r)>>1].c; mid2:=q[(l+r)>>1].r;
     21  repeat
     22   while (mid1>q[i].c)or((mid1=q[i].c)and(mid2>q[i].r)) do inc(i);
     23   while (mid1<q[j].c)or((mid1=q[j].c)and(mid2<q[j].r)) do dec(j);
     24   if i<=j then
     25   begin
     26    swap(q[i],q[j]);
     27    inc(i); dec(j);
     28   end;
     29  until i>j;
     30  if l<j then qsort(l,j);
     31  if i<r then qsort(i,r);
     32 end;
     33 
     34 function gcd(x,y:int64):int64;
     35 var r,t:int64;
     36 begin
     37  if x<y then
     38  begin
     39   t:=x; x:=y; y:=t;
     40  end;
     41  repeat
     42   r:=x mod y;
     43   x:=y;
     44   y:=r;
     45  until r=0;
     46  exit(x);
     47 end;
     48 
     49 procedure add(x,y:longint);
     50 begin
     51  tmp:=tmp-s[a[x]]*s[a[x]];
     52  s[a[x]]:=s[a[x]]+y;
     53  tmp:=tmp+s[a[x]]*s[a[x]];
     54 end;
     55 
     56 procedure modui;
     57 var a,b,c,d,k1,k2,k:int64;
     58     i,j:longint;
     59 begin
     60  a:=1; b:=0; tmp:=0;
     61  for i:=1 to m do
     62  begin
     63   c:=q[i].l; d:=q[i].r;
     64   for j:=b+1 to d do add(j,1);
     65   for j:=c to a-1 do add(j,1);
     66   for j:=a to c-1 do add(j,-1);
     67   for j:=d+1 to b do add(j,-1);
     68   a:=c; b:=d;
     69   if c=d then
     70   begin
     71    ans[i,1]:=0; ans[i,2]:=1;
     72    continue;
     73   end;
     74   k1:=tmp-(d-c+1);
     75   if k1=0 then
     76   begin
     77    ans[i,1]:=0; ans[i,2]:=1;
     78    continue;
     79   end;
     80   k2:=(d-c+1)*(d-c);
     81   k:=gcd(k1,k2);
     82   ans[i,1]:=k1 div k;
     83   ans[i,2]:=k2 div k;
     84  end;
     85 
     86 end;
     87 
     88 procedure qsort1(l,r:longint);
     89 var i,j,mid:longint;
     90     t:int64;
     91 begin
     92  i:=l; j:=r; mid:=q[(l+r)>>1].t;
     93  repeat
     94   while mid>q[i].t do inc(i);
     95   while mid<q[j].t do dec(j);
     96   if i<=j then
     97   begin
     98    swap(q[i],q[j]);
     99    t:=ans[i,1]; ans[i,1]:=ans[j,1]; ans[j,1]:=t;
    100    t:=ans[i,2]; ans[i,2]:=ans[j,2]; ans[j,2]:=t;
    101    inc(i); dec(j);
    102   end;
    103  until i>j;
    104  if l<j then qsort1(l,j);
    105  if i<r then qsort1(i,r);
    106 end;
    107 
    108 begin
    109  assign(input,'bzoj2038.in'); reset(input);
    110  assign(output,'bzoj2038.out'); rewrite(output);
    111  readln(n,m);
    112  for i:=1 to n do read(a[i]);
    113  kuai:=trunc(sqrt(n));
    114  for i:=1 to n do c[i]:=(i-1) div kuai+1;
    115  for i:=1 to m do
    116  begin
    117   readln(q[i].l,q[i].r);
    118   q[i].c:=c[q[i].l];
    119   q[i].t:=i;
    120  end;
    121  qsort(1,m);
    122  modui;
    123  qsort1(1,m);
    124  for i:=1 to m do writeln(ans[i,1],'/',ans[i,2]);
    125  close(input);
    126  close(output);
    127 end.
  • 相关阅读:
    JS调试工具
    什么是Web Service?
    win7怎么安装消息队列 MSMQ
    死锁产生的原因及四个必要条件
    项目管理模式之如何去除SVN标记
    AJAX中的请求方式以及同步异步的区别
    敏捷软件开发模型--SCRUM
    堆和栈
    UI产品设计流程中的14个要点
    Android中dp和px之间进行转换
  • 原文地址:https://www.cnblogs.com/myx12345/p/6477945.html
Copyright © 2020-2023  润新知