一节政治课的结果……推式子+推式子+推式子……

  首先注意到一个区间里面,选择(x, y)和(y, x)的费用是一样的。所以我们把这两种情况合为一种,那么现在询问的区间为(l, r),则一共的情况就有 1 / (k + 1)*(k)种 (k = r - l + 1)。所以我们只需要求出区间内所有的子集之和 * 2 / (k + 1) * k(每种情况有两种)。但这样复杂度还是太高了,我们考虑继续推下式子。

  顺着一个比较常见的思路想:分离出每一段路对于答案的贡献再累加起来。那么我们的ans = Vx(这一段路的代价) * 包含了这条道路的区间个数。包含了第x条道路的区间个数一共是(x - l + 1) * (r - x)。但这个东西我们不好维护,所以将它拆分一下,尽量分离出不变的量。这个东西就等于:((rx + lx) - (x * x + x) + (r - l * r))* Vx。由此, 问题转化为维护区间内的 Vx 之和, Vx * x之和, 与 Vx * x * (x + 1)之和。线段树完美解决!

// luogu-judger-enable-o2
#include <bits/stdc++.h>
using namespace std;
#define maxn 100005
#define int unsigned long long
int n, m, mark[maxn * ]; struct tree
{
int l, r, num[], size, x, xx;
}T[maxn * ]; int read()
{
int x = , k = ;
char c;
c = getchar();
while(c < '' || c > '') { if(c == '-') k = -; c = getchar(); }
while(c >= '' && c <= '') x = x * + c - '', c = getchar();
return x * k;
} void Build(int p, int l, int r)
{
T[p].l = l, T[p].r = r, T[p].size = (r - l + );
if(l == r)
{
T[p].num[] = T[p].num[] = T[p].num[] = ;
T[p].x = l, T[p].xx = T[p].x * (T[p].x + );
return;
}
int mid = (l + r) >> ;
Build(p << , l, mid), Build(p << | , mid + , r);
T[p].x = T[p << ].x + T[p << | ].x;
T[p].xx = T[p << ].xx + T[p << | ].xx;
return;
} void push_up(int p, int num)
{
T[p].num[] += num * T[p].x;
T[p].num[] += num * T[p].xx;
T[p].num[] += num * T[p].size;
mark[p] += num;
} void push_down(int p)
{
if(!mark[p]) return;
push_up(p << , mark[p]);
push_up(p << | , mark[p]);
mark[p] = ;
} void update(int p, int l, int r, int num) // num1 :Vx * x, num2 :Vx * x * (x + 1), num3 : Vx;
{
int mid = (l + r) >> ;
int L = T[p].l, R = T[p].r;
if(L >= l && R <= r)
{
push_up(p, num);
return;
}
if(R < l || L > r) return;
push_down(p);
update(p << , l, r, num), update(p << | , l, r, num);
T[p].num[] = T[p << ].num[] + T[p << | ].num[];
T[p].num[] = T[p << ].num[] + T[p << | ].num[];
T[p].num[] = T[p << ].num[] + T[p << | ].num[];
} int query(int p, int l, int r, int opt)
{
int L = T[p].l, R = T[p].r;
if(R < l || L > r) return ;
if(L >= l && R <= r) return T[p].num[opt];
push_down(p);
return query(p << , l, r, opt) + query(p << | , l, r, opt);
} int Get(int a, int b)
{
while(b)
{
int c = a % b;
a = b;
b = c;
}
return a;
} signed main()
{
n = read(), m = read();
Build(, , n);
for(int i = ; i <= m; i ++)
{
char c;
cin >> c;
int l = read(), r = read();
if(c == 'C')
{
int v = read();
update(, l, r - , v);
}
else // num1 :Vx * x, num2 :Vx * x * (x + 1), num3 : Vx;
{
int ans = query(, l, r - , ) * (l + r);
ans -= query(, l, r - , );
ans += query(, l, r - , ) * (r - l * r);
int K = (r - l + ) * (r - l);
int GCD = Get(ans * , K);
printf("%lld/%lld\n", ans * / GCD, K / GCD);
}
}
return ;
}

【题解】HAOI2012高速公路的更多相关文章

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

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

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

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

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

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

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

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

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

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

  6. [Luogu 2221] HAOI2012 高速公路

    [Luogu 2221] HAOI2012 高速公路 比较容易看出的线段树题目. 由于等概率,期望便转化为 子集元素和/子集个数. 每一段l..r中,子集元素和为: \(\sum w_{i}(i-l+ ...

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

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

  8. BZOJ2752:[HAOI2012]高速公路——题解

    http://www.lydsy.com/JudgeOnline/problem.php?id=2752 https://www.luogu.org/problemnew/show/P2221#sub ...

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

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

随机推荐

  1. Ajax在表单中的应用

    ajax在注册用户表单中的使用 1.验证用户名是否被使用 2.获取手机短信验证码 3.点击表单中的图片刷新,可实现刷新图片验证码 <!DOCTYPE html> <html> ...

  2. narcissus

    public class narcissus { public static void main(String args[]) { long u=0,t=0,h=0,y=0,k=0; for(long ...

  3. POJ2553 汇点个数(强连通分量

    The Bottom of a Graph Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 12070   Accepted: ...

  4. 黑洞数--python

    黑洞数:黑洞数又称陷阱数,是类具有奇特转换特性的整数.任何一个数字不全相同整数,经有限“重排求差”操作,总会得某一个或一些数,这些数即为黑洞数.“重排求差”操作即把组成该数的数字重排后得到的最大数减去 ...

  5. python2.7入门---字符串

        这次咱们就来看一下python的字符串类型.首先我们要知道,字符串是 Python 中最常用的数据类型.我们可以使用引号('或")来创建字符串.创建字符串很简单,只要为变量分配一个值 ...

  6. 关于 SSH Server 的整体设定

    # . 关于 SSH Server 的整体设定,包含使用的 port 啦,以及使用的密码演算方式 Port # SSH 预设使用 这个 port,您也可以使用多的 port ! # 亦即重复使用 po ...

  7. 3招搞定APP注册作弊

    在说如何应对之前,易盾先给各位盾友梳理移动端APP可能遇到哪些作弊风险.1. 渠道商刷量,伪造大量的下载量和装机量,但没有新用户注册:2. 对于电商.P2P.外卖等平台,会面临散户或者团队刷子的注册- ...

  8. 程序员编程利器:20款最好的免费的IDEs和编辑器

    程序员编程利器:20款最好的免费的IDEs和编辑器 还没转眼明年可就大年三十了,忙的可真是晕头转了个向,看着亲朋好友们那让人欣羡的小肚腩,不禁感慨,岁月是一把猪饲料,绿了芭蕉,肥了那杨柳小蛮腰,可怜我 ...

  9. 最小总代价 状压DP

    描述 n个人在做传递物品的游戏,编号为1-n. 游戏规则是这样的:开始时物品可以在任意一人手上,他可把物品传递给其他人中的任意一位:下一个人可以传递给未接过物品的任意一人. 即物品只能经过同一个人一次 ...

  10. Kotlin怎样使用Android的Dagger2

    作者:Antonio Leiva 时间:Apr 11, 2017 原文链接:https://antonioleiva.com/dagger-android-kotlin/ 在Android上,创建去耦 ...