试题来源

  2013中国国家集训队第二次作业

问题描述

  osu!是一个基于《押忍!战斗!应援团》《精英节拍特工》《太鼓达人》等各种音乐游戏做成的一款独特的PC版音乐游戏。游戏中,玩家需要根据音乐的节奏,通过鼠标点击或敲击按键合成一首歌曲。
  一张osu!的地图是由若干个“音”排列而成的。在本题中,对于每个音我们只需要考虑成功点击和错过(miss)这两种情况。对于一张osu!地图,玩家的完成情况可以用一个01串表示(0代表miss,1代表成功)。在本题中,使用如下计分规则:将玩家完成一张地图的01串中所有的0删去,则这个串可能会断裂成若干段连续的1。对于一段长度为L的1(L≥1),你的总分会增加L^2+L+1。例如:一张地图有10个音,某玩家完成情况为1011101110,则删除所有0后得到的是“1”“111”和“111”。因此这个玩家的得分为(1+1+1)+(9+3+1)+(9+3+1)=29。
  ACMonster要给Sandytea出一张osu!的地图。在一张图中,不同音对于Sandytea而言难度可能是不同的。我们定义一个音的难度系数为Sandytea成功完成这个音的概率,因此这个难度系数是介于0和1之间的。
  现在ACMonster写下了一个包含N个音的序列,但是他不想直接把这个序列做成地图,而是选择其中的某个片段。设S(X,Y)代表序列上第X个音到第Y个音构成的序列,ACMonster想知道如果把S(X,Y)对应的序列做成地图,Sandytea的期望得分是多少。有时ACMonster会觉得某个音的难度系数不太合理,因此要进行修改。请你想办法处理ACMonster的修改,并回答他提出的问题。

输入格式

  第一行包含两个数N和M,N代表序列中音的个数,M代表询问及修改的总次数。
  第二行至第(N+1)行每行包含一个实数,第i行的实数表示第(i-1)个音的难度系数。
  第(N+2)行至第(N+M+1)行每行包含三个数Type,X和Y。
  如果Type=0,代表ACMonster询问S(X,Y)的期望得分,保证X和Y为整数,1≤X≤Y≤N。
  如果Type=1,代表ACMonster要把第X个音的难度系数修改为Y,保证X为整数,1≤X≤N,0≤Y≤1。

输出格式

  对于输入中所有询问,按照出现的顺序输出相应的答案,四舍五入保留两位小数。

样例输入

2 3
0.5
0.5
0 1 2
1 1 0
0 1 2

样例输出

3.25
1.50

样例说明

  对于第一次询问,00,01,10,11这四种情况出现的概率均为1/4,得分分别为0,3,3,7。因此期望得分为(0+3+3+7)/4=3.25。
  对于第二次询问,00,01这两种情况出现的概率均为1/2,得分分别为0,3。因此期望得分为(0+3)/2=1.50。

数据规模和约定

  20%的数据满足N,M≤5000;
  60%的数据满足N,M≤50000;
  100%的数据满足N,M≤500000。


小规模数据可以套bzoj4318

满分算法用线段树,分别维护平方、一次方、1,然后1和一次方可以直接合并,平方那个推一下发现是一个线性递推式,可以构造3*3的矩阵。

因为这个题及其卡常,我们发现矩乘的时候真正有用的变量只有四个,所以可以分别维护,减少常数

然而并没有什么卵用,我的代码是75分,被卡常了,求老司机带我卡常

我发现我风格分好高

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
using namespace std;
typedef long long LL;
const int SZ = 500010;
const int INF = 1000000010;
struct segment{int l,r;double s0,s1,a11,a12,a31,a32,lx,rx;
}tree[SZ << 2];
double a[SZ];
void update(segment &p,const segment &a,const segment &b)
{p.s0 = a.s0 + b.s0 - a.rx * b.lx;p.s1 = a.s1 + b.s1;p.a11 = a.a11 * b.a11;p.a12 = a.a11 * b.a12 + a.a12;p.a31 = a.a31 * b.a11 + b.a31;p.a32 = a.a31 * b.a12 + a.a32 + b.a32;p.lx = a.lx; p.rx = b.rx;
}
void build(int p,int l,int r)
{tree[p].l = l,tree[p].r = r;if(l == r){tree[p].lx = tree[p].rx = tree[p].s1 = tree[p].s0 = a[l];tree[p].a11 = tree[p].a31 = tree[p].a32 = a[l];tree[p].a12 = a[l] * 2;return ; }int mid = (l + r) >> 1;build(p << 1,l,mid); build(p << 1 | 1,mid + 1,r);update(tree[p],tree[p << 1],tree[p << 1 | 1]);
}
segment ask(int p,int l,int r)
{if(l == tree[p].l && tree[p].r == r)return tree[p]; int mid = (tree[p].l + tree[p].r) >> 1;if(l > mid) return ask(p << 1 | 1,l,r);else if(r <= mid) return ask(p << 1,l,r);else{segment a = ask(p << 1,l,mid),b = ask(p << 1 | 1,mid + 1,r);segment ans;update(ans,a,b);return ans;}
}
void change(int p,int pos,double d)
{if(tree[p].l == tree[p].r){tree[p].lx = tree[p].rx = tree[p].s1 = tree[p].s0 = d;tree[p].a11 = tree[p].a31 = tree[p].a32 = d;tree[p].a12 = d * 2;return ;}int mid = (tree[p].l + tree[p].r) >> 1;if(pos <= mid) change(p << 1,pos,d);else change(p << 1 | 1,pos,d);update(tree[p],tree[p << 1],tree[p << 1 | 1]);
}
void scan(int &n)
{n = 0;char a = getchar();while(a < '0' || a > '9') a = getchar();while(a >= '0' && a <= '9') n = n * 10 + a - '0',a = getchar();
}
int main()
{int n,m;scan(n); scan(m);for(int i = 1;i <= n;i ++)scanf("%lf",&a[i]);build(1,1,n);while(m --){int opt;scan(opt);if(opt == 0){int x,y;scan(x); scan(y);segment ans = ask(1,x,y);printf("%.2lf\n",ans.s0 + ans.s1 + ans.a32);}else{int x; double y;scan(x);scanf("%lf",&y);change(1,x,y);}}return 0;
}

【tsinsen A1490】osu!(乔明达) 矩阵+线段树相关推荐

  1. 【周末狂欢赛6】[AT1219]历史研究(回滚莫队),大魔法师(矩阵+线段树),单峰排列

    文章目录 T1:单峰排列 题目 题解 code T2:历史研究 题目 题解 code T3:大魔法师 题目 题解 code 我可能这辈子都更不出来狂欢赛5了,先咕咕 T1:单峰排列 题目 一个n的全排 ...

  2. ZJOI2019 线段树

    ZJOI2019 线段树 题意: 题目传送门 题解: 来讲一个非常卡常的矩阵+线段树做法.首先转化一下题意,直接将\(2^m\)棵线段树建出来一定是不现实的,我们对于每一个节点,记录这个节点在所有线段 ...

  3. A1490. osu!(乔明达)|概率与期望|卡常|矩阵

    60TLE 把要求信息拆分 用 线段树和矩阵维护 upd:fqk太劲了 加个读入优化就A过去了 #include <cstdio> #include <iostream> #i ...

  4. [TsinsenA1490] osu!(乔明达)

    作为一名osu!玩家,这道题成功吸引到了我... 题意 长度为n的序列,给出每一个数字可能为1的概率aia_i,每个数字为0的概率为1−ai1-a_i.两个操作:修改某个数字的概率,询问一段区间得分期 ...

  5. CodeForces - 1252K Addition Robot(线段树维护矩阵)

    题目链接:点击查看 题目大意:给出一个只由 A 和 B 组成的字符串 s ,需要完成 m 次操作,每次操作分为两种类型: 1 l r :将 [ l , r ] 内的字符串 A 变成 B,B 变成 A ...

  6. 牛客 - 求函数(线段树+区间合并/线段树+矩阵维护)

    题目链接:点击查看 题目大意:现在有 n 个函数,每个函数都是诸如 f( x ) = k * x + b 的形式,只是每个函数的 k 和 b 都是相互独立的,现在给出两个操作: 1 pos k b:将 ...

  7. 2019ICPC(南昌) - Hello 2019(动态规划+线段树维护矩阵)

    题目链接:点击查看 题目大意:给出一个长度为n的只由数字组成的字符串,再给出m个询问,每次询问给出闭区间[l,r],求区间内想要包含"9102",但不包含"8102&qu ...

  8. 线段树 + 矩阵 --- ZOJ 3772 Calculate the Function

    Calculate the Function Problem's Link:   http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCod ...

  9. New Year and Old Subsequence CodeForces - 750E(线段树+矩阵dp)2019南昌icpc网络赛Hello 2019

    A string t is called nice if a string "2017" occurs in t as a subsequence but a string &qu ...

最新文章

  1. git 强制推送_Git 常用命令清单,掌握这些,轻松驾驭版本管理
  2. 扇贝编程python是干嘛的-产品观察 | 以对话式互动学习撬动转化,扇贝编程瞄准职教市场...
  3. 最简单的composer 包 使用
  4. 串口IDLE空闲中断+DMA实现接收不定长数据基于stm32cubemx
  5. 使用 gRPCurl 调试.NET 5的gPRC服务
  6. API:互联网是如何在幕后工作的?
  7. 让你事半功倍的小众 Python库
  8. java 获取项目下的webapp_Spring Boot2 系列教程(一)纯 Java 搭建 SSM 项目
  9. 数据结构之王道视频中留下的问题
  10. 通过INI文件实现HYDRA各插件间对象共享
  11. 10. 在constructors内阻止资源泄露
  12. dcs系统中数据服务器的冗余,如何提升DCS系统的可靠性?这篇文章讲透了
  13. raw socket 编程实例
  14. 环境微生物复习题及答案
  15. 我不是九爷 带了解 Unity3D与VR虚拟现实
  16. checkv的基本使用
  17. Heatmap Plot with ggplot2 【R】
  18. 如何提取文件名称到excel
  19. 代码实践:MLP的反向传播算法
  20. webix, DataTable组件,给表头增加Tooltip

热门文章

  1. 谈谈Word2Vec的CBOW模型
  2. 货物监控设备开发中,关于EC600S和BG95模块开机方式差异的说明
  3. cocos3 图片按照椭圆运动
  4. 一单一议让你头大?产品责任险的费率和报价全解析
  5. 自制微信机器人:群发消息、自动接收好友
  6. 【互联网的恩怨情仇】盘点2015年互联网十大撕逼事件
  7. 2018仁爱英语7年级下册U6T2学科讲义(有答案)
  8. rdma软件架构的理解。
  9. 大型支付系统后台对账系统的控制和管理
  10. 太阳能热水器两芯液位温度检测