zoukankan      html  css  js  c++  java
  • 【BZOJ3939】Cow Hopscotch(动态开点线段树)

    题意:

    就像人类喜欢跳格子游戏一样,FJ的奶牛们发明了一种新的跳格子游戏。虽然这种接近一吨的笨拙的动物玩跳格子游戏几乎总是不愉快地结束,但是这并没有阻止奶牛们在每天下午参加跳格子游戏 
    游戏在一个R*C的网格上进行,每个格子有一个取值在1-k之间的整数标号,奶牛开始在左上角的格子,目的是通过若干次跳跃后到达右下角的格子,当且仅当格子A和格子B满足如下条件时能从格子A跳到格子B: 
    1.B格子在A格子的严格右方(B的列号严格大于A的列号) 
    2.B格子在A格子的严格下方(B的行号严格大于A的行号) 
    3.B格子的标号和A格子的标号不同 
    请你帮助奶牛计算出从左上角的格子到右下角的格子一共有多少种不同的方案
    n,m<=750,k<=n*m
     
    思路:这题是金组的数据范围
    在铜组因为数据小 裸的dp可做 金组需要优化
     [ dp[i,j]= sum_{x=1}^{i-1}  sum_{y=1}^{j-1}  dp[x,y]         (a[i,j]<>a[x,y]) ] 
    转化为左上角的所有方案-该颜色的所有方案
    因为只要求保存一个版本
    可以用一棵动态开点的线段树解决
    修改时使用类似于主席树的方法
     1 const mo=1000000007;
     2 var t:array[0..7000000]of record
     3                            l,r,s:longint;
     4                           end;
     5 
     6     sum,a,dp:array[0..800,0..800]of longint;
     7     root:array[0..1000000]of longint;
     8     f:array[0..800]of longint;
     9     n,m,i,j,s1,s2,cnt,k:longint;
    10 
    11 procedure pushup(x:longint);
    12 var l,r:longint;
    13 begin
    14  l:=t[x].l; r:=t[x].r;
    15  t[x].s:=(t[l].s+t[r].s) mod mo;
    16 end;
    17 
    18 procedure update(var p:longint;l,r,x,v:longint);
    19 var mid:longint;
    20 begin
    21  if p=0 then
    22  begin
    23   inc(cnt); p:=cnt;
    24  end;
    25  if l=r then
    26  begin
    27   t[p].s:=(t[p].s+v) mod mo; exit;
    28  end;
    29  mid:=(l+r)>>1;
    30  if x<=mid then update(t[p].l,l,mid,x,v)
    31   else update(t[p].r,mid+1,r,x,v);
    32  pushup(p);
    33 end;
    34 
    35 function query(p,l,r,x,y:longint):longint;
    36 var mid:longint;
    37 begin
    38 
    39  if (p=0)or(x>y) then exit(0);
    40  if (x<=l)and(y>=r) then exit(t[p].s);
    41  mid:=(l+r)>>1;
    42  query:=0;
    43  if x<=mid then query:=(query+query(t[p].l,l,mid,x,y)) mod mo;
    44  if y>mid then query:=(query+query(t[p].r,mid+1,r,x,y)) mod mo;
    45 end;
    46 
    47 
    48 begin
    49 // assign(input,'bzoj3939.in'); reset(input);
    50 // assign(output,'bzoj3939.out'); rewrite(output);
    51  readln(n,m,k);
    52  for i:=1 to n do
    53   for j:=1 to m do read(a[i,j]);
    54 
    55  dp[1,1]:=1;
    56  for i:=1 to m do sum[1,i]:=1;
    57  update(root[a[1,1]],1,m,1,1);
    58 
    59  for i:=2 to n do
    60  begin
    61   for j:=m downto 1 do
    62   begin
    63    s1:=sum[i-1,j-1];
    64    s2:=query(root[a[i,j]],1,m,1,j-1);
    65    dp[i,j]:=((s1-s2) mod mo+mo) mod mo;
    66    update(root[a[i,j]],1,m,j,dp[i,j]);
    67   end;
    68   for j:=1 to m do
    69   begin
    70    f[j]:=(f[j-1]+dp[i,j]) mod mo;
    71    sum[i,j]:=(sum[i-1,j]+f[j]) mod mo;
    72   end;
    73  end;
    74   writeln(dp[n,m]);
    75  {for i:=1 to n do
    76  begin
    77   for j:=1 to m do write(dp[i,j],' ');
    78   writeln;
    79  end; }
    80 
    81 
    82  close(input);
    83  close(output);
    84 end.
     
  • 相关阅读:
    oracle数据库的乱码问题解决方案
    @HTML.checkboxFor()用法
    存储过程实现登录(.net)
    .net中大数据的处理
    xml总结
    获取指定日期是当前月的第几周
    JS中正则方法的使用
    获取指定日期的前一天日期
    通过Oracle函数实现.NET String.Format函数的简单版
    ReportViewer实现多语言
  • 原文地址:https://www.cnblogs.com/myx12345/p/6424132.html
Copyright © 2011-2022 走看看