[Luogu 2221] HAOI2012 高速公路

<题目链接>


比较容易看出的线段树题目。

由于等概率,期望便转化为 子集元素和/子集个数。

每一段l..r中,子集元素和为:

\(\sum w_{i}(i-l+1)(r-i)\) //\((i-l+1)(r-i)\)是每个数用到的次数

\(=\sum w_{i}((r-lr)+(l+r-1)i-i^{2})\)

\(=(r-lr)\sum w_{i}+(l+r-1)\sum i\times w_{i}-\sum i^{2}\times w_{i}\)

由此观之,线段树需要维护\(\sum w_{i}\)v[0]、\(\sum i\times w_{i}\)v[1]、\(\sum i^{2}\times w_{i}\)v[2]

有这样一个神奇的公式:

\(1^{2}+2^{2}+\dots+n^{2}=n(n+1)(2n+1)/6\)

所以,在进行Update操作时,设size=r-l+1,改变量为v

v[0]+=v*size;
v[1]+=v*size*(l+r)>>1;
v[2]+=v*(r*(r+1)*((r<<1)+1)-(l-1)*l*((l<<1)-1))/6LL;

记得开long long以及各种强制转int为long long!隐式类型转换简直天坑。

线段树基础不扎实的我这题调了一天…

#include <cstdio>
#include <cstring>
const int MAXN=100010;
int n,m;
class SegmentTree
{
public:
SegmentTree(void)
{
memset(s,0,sizeof s);
}
void BuildTree(int i,int l,int r)
{
s[i].l=l,s[i].r=r;
if(l==r)
return;
int j=i<<1,mid=l+r>>1;
BuildTree(j,l,mid),BuildTree(j+1,mid+1,r);
}
void Add(int i,int l,int r,long long v)
{
if(l==s[i].l && r==s[i].r)
{
Update(i,v);
return;
}
if(s[i].l!=s[i].r && s[i].lazy)
PushDown(i);
int j=i<<1,mid=s[i].l+s[i].r>>1;
if(r<=mid)
Add(j,l,r,v);
else if(l>mid)
Add(j+1,l,r,v);
else
Add(j,l,mid,v),Add(j+1,mid+1,r,v);
PushUp(i);
}
void Ans(long long l,long long r)
{
long long t,ans,cnt=(r-l+1)*(r-l)>>1LL,sum[3];
for(int i=0;i<3;++i)
sum[i]=Sum(1,l,r-1,i);
ans=sum[0]*(r-l*r)+sum[1]*(l+r-1)-sum[2];
t=GCD(ans,cnt);
printf("%lld/%lld\n",ans/t,cnt/t);
}
private:
struct node
{
int l,r;
long long lazy,v[3];
}s[MAXN<<2];
long long GCD(long long x,long long y)
{
return !y ? x : GCD(y,x%y);
}
void Update(int i,long long v)
{
long long l=s[i].l,r=s[i].r,size=r-l+1;
s[i].lazy+=v;
s[i].v[0]+=v*size;
s[i].v[1]+=v*size*(l+r)>>1;
s[i].v[2]+=v*(r*(r+1)*((r<<1)+1)-(l-1)*l*((l<<1)-1))/6LL;
}
void PushUp(int i)
{
for(int j=0;j<3;++j)
s[i].v[j]=s[i<<1].v[j]+s[i<<1|1].v[j];
}
void PushDown(int i)
{
int j=i<<1;
Update(j,s[i].lazy),Update(j+1,s[i].lazy);
s[i].lazy=0;
}
long long Sum(int i,int l,int r,int k)
{
if(l==s[i].l && r==s[i].r)
return s[i].v[k];
if(s[i].l!=s[i].r && s[i].lazy)
PushDown(i);
int j=i<<1,mid=s[i].l+s[i].r>>1;
if(r<=mid)
return Sum(j,l,r,k);
else if(l>mid)
return Sum(j+1,l,r,k);
else
return Sum(j,l,mid,k)+Sum(j+1,mid+1,r,k);
}
}T;
int main(int argc,char *argv[])
{
scanf("%d %d",&n,&m);
T.BuildTree(1,1,n-1);
for(int i=1,l,r,v;i<=m;++i)
{
char c;
scanf("\n%c %d %d",&c,&l,&r);
if(c=='C')
{
scanf("%d",&v);
T.Add(1,l,r-1,v);
}
else
T.Ans(l,r);
}
return 0;
}

谢谢阅读。

[Luogu 2221] HAOI2012 高速公路的更多相关文章

  1. 【题解】Luogu P2221 [HAOI2012]高速公路

    原题传送门 这道题还算简单 我们要求的期望值: \[\frac{\sum_{i=l}^r\sum_{j=l}^rdis[i][j]}{C_{r-l+1}^{2}}\] 当然是上下两部分分别求,下面肥肠 ...

  2. luogu P2221 [HAOI2012]高速公路题解

    题面 很套路的拆式子然后线段树上维护区间和的题.一般都是把式子拆成区间内几个形如\(\sum i*a_i, \sum i^2 * a_i\)的式子相加减的形式. 考虑一次询问[l,r]的答案怎么算: ...

  3. BZOJ2752: [HAOI2012]高速公路(road)

    2752: [HAOI2012]高速公路(road) Time Limit: 20 Sec  Memory Limit: 128 MBSubmit: 608  Solved: 199[Submit][ ...

  4. BZOJ 2752: [HAOI2012]高速公路(road)( 线段树 )

    对于询问[L, R], 我们直接考虑每个p(L≤p≤R)的贡献,可以得到 然后化简一下得到 这样就可以很方便地用线段树, 维护一个p, p*vp, p*(p+1)*vp就可以了 ----------- ...

  5. 【线段树】BZOJ2752: [HAOI2012]高速公路(road)

    2752: [HAOI2012]高速公路(road) Time Limit: 20 Sec  Memory Limit: 128 MBSubmit: 1621  Solved: 627[Submit] ...

  6. BZOJ 2752: [HAOI2012]高速公路(road) [线段树 期望]

    2752: [HAOI2012]高速公路(road) Time Limit: 20 Sec  Memory Limit: 128 MBSubmit: 1219  Solved: 446[Submit] ...

  7. P2221 [HAOI2012]高速公路(线段树)

    P2221 [HAOI2012]高速公路 显然答案为 $\dfrac{\sum_{i=l}^r\sum_{j=l}^{r}dis[i][j]}{C_{r-l+1}^2}$ 下面倒是挺好算,组合数瞎搞 ...

  8. BZOJ 2752:[HAOI2012]高速公路(road)(线段树)

    [HAOI2012]高速公路(road) Description Y901高速公路是一条重要的交通纽带,政府部门建设初期的投入以及使用期间的养护费用都不低,因此政府在这条高速公路上设立了许多收费站.Y ...

  9. 【BZOJ2752】【Luogu P2221】 [HAOI2012]高速公路

    不是很难的一个题目.正确思路是统计每一条边被经过的次数,但我最初由于习惯直接先上了一个前缀和再推的式子,导致极其麻烦难以写对而且会爆\(longlong\). 推导过程请看这里. #include & ...

随机推荐

  1. Android开发 使用 adb logcat 显示 Android 日志

    作者 : 万境绝尘  转载请著名出处 eclipse 自带的 LogCat 工具太垃圾了, 开始用 adb logcat 在终端查看日志; 1. 解析 adb logcat 的帮助信息 在命令行中输入 ...

  2. 计算器软件实现系列(七)WPF+SQL+策略模式

    一  整体概述 本次设计主要是在WPF的页面中实现的,属于表现层的更换,数据库部分用的还是数据库的封装,其中引用了策略模式 二  设计思路 1 在出题页面,进行试题的编辑,在编辑后会自动保存到数据库中 ...

  3. 如何重新安装Orchard CMS?

    Orchard CMS安装后,配置文件和数据库保存在App_Data目录中.这个目录是受保护的,是不能通过网址访问到的. 如果要完全重装你的站点,你可以删除此目录中的所有文件,但是最好先备份!删除后重 ...

  4. 3ds Max学习日记(七)

      第7章讲的是多边形建模,实例略多,有十六个,再加上周日的怠惰感,只做了几个实例. 附上今日的劳动成果:   布料(创建一个平面,转换为可编辑多边形,然后调整顶点,连接一些边,添加网格平滑,转换为可 ...

  5. Windows2008安装启用无线网卡

    昨天给本子换了系统来着,本来想法是好的,想在本子上安装Hyper-v来搭建多平台VPS,这样的话就能玩多个系统了,对于我自己来说对娱乐没啥兴趣,扯多了,正文 笔记本安装什么都很顺利,但是无线网卡把我难 ...

  6. 《Effective C#》快速笔记(四)- 使用框架

    .NET 是一个类库,你了解的越多,自己需要编写的代码就越少. 目录 三十.使用重写而不是事件处理函数 三十一.使用 IComparable<T> 和 IComparer<T> ...

  7. 在临床医学里面,bid、tid、qid和q3w是什么意思啊??这些缩写的全称是怎么写呢??

    { value: 'QD', name: 'QD 每日一次' }, { value: 'BID', name: 'BID 每日两次' }, { value: 'TID', name: 'TID 每日三 ...

  8. Delphi:ADOConnection连接SQLServer自动断网问题解决

    =============================== 解决方法一:异常时关闭连接,WinXP,win7 32位大部分情况都是起作用的,不过在有些windows操作系统下(如家庭版)不起作用, ...

  9. Greenlet-手动切换

    yield()是自己写的协程,Greenlet( )是已经封装好了的协程. 协程:遇到 I/O 操作就切换到别的地方了(先去处理其他携程去了).等原协程的 I/O 操作一完成就切回去.这样就把 I/O ...

  10. BZOJ1412 [ZJOI2009]狼和羊的故事 【最小割】

    1412: [ZJOI2009]狼和羊的故事 Time Limit: 10 Sec  Memory Limit: 162 MB Submit: 3454  Solved: 1733 [Submit][ ...