中位数及带权中位数题集

codevs 3625

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 int x[11111], y[11111];
 4 int main()
 5 {
 6     int n; scanf("%d", &n);
 7     for(int i = 1; i <= n; i++) scanf("%d %d", &x[i], &y[i]);
 8     ///先处理y
 9     sort(y + 1, y + n + 1);
10     long long ans = 0;
11     int mid = n / 2 + 1;
12     for(int i = 1; i <= n; i++) ans += abs(y[mid] - y[i]);
13     ///再处理x
14     sort(x + 1, x + n + 1);
15     for(int i = 1; i <= n; i++) x[i] -= (i - 1);
16     sort(x + 1, x + n + 1);
17     for(int i = 1; i <= n; i++) ans += abs(x[mid] - x[i]);
18     printf("%lld\n", ans);
19     return 0;
20 }

Code

Codeforces Round #512 (Div. 2, based on Technocup 2019 Elimination Round 1) F. Putting Boxes Together

题解真的又写的非常清楚了……

自己在想的时候,确实想到肯定有一个块不动,其他的动,我们只需要去移那些贡献小的,我猜是最重的那个,但自己写了组样例就推翻了。

题解讲,用$S(l,r)$表示将索引$(l,r)$物品移动一步的花费,不动的那块应该满足$S(l,k-1)≤ \frac{S(l,r)}{2}$,$S(l,k)> \frac{S(l,r)}{2}$。Q神说是熟知的带权中位数问题

求$k$的过程,可以用二分+树状数组解决。

求得$k$后,因为$k$是固定不动的,如果$i<k$,那么花费是$\sum_{i \in[l, k-1]} {w_{i}(a_{k}-a_{i}-(k-i))}$,令$a_{i}=a_{i}-i$,那么原式$= \sum_{i \in[l, k-1]} {w_{i}(a_{k}-a_{i})}=a_{k}\times S(l,k-1)-\sum_{i \in[l, k-1]} {w_{i}a_{i}}$,再用一颗树状数组来维护$w_{i} a_{i}$就可以了。$i > k$类似。

真的是慎用除法,不然都不知道怎么死的……

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll mod = 1e9 + 7;
const int maxn = 2e5 + 50;
ll a[maxn], w[maxn];
ll C[maxn];
int n, q;
void add1(int x, ll v)
{
    while(x <= n)
    {
        C[x] += v;
        x += x & -x;
    }
}
ll query1(int x)
{
    ll res = 0;
    while(x > 0)
    {
        res += C[x];
        x -= x & -x;
    }
    return res;
}
ll calc(int l, int r)
{
    if(r < l) return 0;
    ll ans = query1(r) - query1(l - 1);
   // printf("%lld\n", ans);
    return ans;
}
ll D[maxn];
void add2(int x, ll v)
{
    while(x <= n)
    {
        D[x] += v;
        D[x] %= mod;
        x += x & -x;
    }
}
ll query2(int x)
{
    ll res = 0;
    while(x > 0)
    {
        res += D[x];
        res %= mod;
        x -= x & -x;
    }
    return res;
}
ll calc2(int l, int r)
{
    if(r < l) return 0;
    return (query2(r) - query2(l - 1) + mod) % mod;
}
int main()
{
    scanf("%d %d", &n, &q);
    for(int i = 1; i <= n; i++) scanf("%lld", &a[i]);
    for(int i = 1; i <= n; i++) scanf("%lld", &w[i]), add1(i, w[i]), a[i] = a[i] - i, add2(i, w[i] * a[i] % mod);
    while(q--)
    {
        int l, r; scanf("%d %d", &l, &r);
        ///首先二分
        if(l > 0)
        {
            ll S = calc(l, r);
            int k = 0;
            int tmpl = l, tmpr = r;
            while(tmpl <= tmpr)
            {
                int mid = (tmpl + tmpr) >> 1;
                if(calc(l, mid - 1) * 2LL < S && calc(l, mid) * 2LL < S)
                {
                    tmpl = mid + 1;
                }
                else if(calc(l, mid - 1) * 2LL > S && calc(l, mid) * 2LL > S)
                {
                    tmpr = mid - 1;
                }
                else
                {
                    k = mid;
                    break;
                }
            }
            ///得到k后,开始计算花费
            ll ans = (calc(l, k - 1) % mod * a[k] % mod - calc2(l, k - 1) + mod) % mod;
            ans = (ans + (calc2(k + 1, r) - calc(k + 1, r) % mod * a[k] % mod + mod) % mod) % mod;
            printf("%lld\n", ans);
        }
        else
        {
            int id = -l;
            ll nw = r;
            add1(id, nw - w[id]), add2(id, (a[id] * nw % mod - a[id] * w[id] % mod + mod) % mod);
            w[id] = nw;
        }
    }
    int ccc = 0;
    return 0;
}

Code

sgu 114

POJ 1723 SOLDIERS

POJ 1160

ZOJ 1196

原文地址:https://www.cnblogs.com/wangwangyu/p/9696761.html

时间: 2024-11-10 19:43:12

中位数及带权中位数题集的相关文章

[总结]中位数及带权中位数问题

目录 一.中位数问题 1. 问题模型 2. 结论 3. 推导 4. 例题 二.带权中位数问题 1. 问题模型 2. 结论 3. 推导 4. 例题 一.中位数问题 1. 问题模型 数轴\(x\)上有\(n\)个点,现在给出这\(n\)个点的坐标\(a[i](i\in [1,n])\),让你选择一个点\(k(k\in [1,n])\),使得每个点到点\(k\)的距离之和最小. 2. 结论 点\(k\)为序列的中位数时最优: 若n为奇数,点\(k\)位于a[(n+1)/2]处最优:若n为偶数,点\(k

Valentine&#39;s Day Round hdu 5176 The Experience of Love [好题 带权并查集 unsigned long long]

传送门 The Experience of Love Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 221    Accepted Submission(s): 91 Problem Description A girl named Gorwin and a boy named Vivin is a couple. They arriv

[POJ 1723]SOLDIERS(带权中位数问题)

题目链接:http://poj.org/problem?id=1723 最近因为在为NOIP 2014复习,一直没写啥题解... 这个题目的意思是给你n个士兵在棋盘里的坐标,要你将他们排成连续的一行(即与x轴平行),问你最少要将这些士兵移动多少步. 思路:设最终连续的一行的开头坐标为(linex,liney),终点坐标为(linex+n-1,liney) 将x坐标和y坐标分开讨论. y坐标上,要让士兵移动步数最少,则liney=士兵们的y坐标的中位数 x坐标上士兵的移动步数=|x1-linex|

poj 1723 SOLDIERS 带权中位数

题目 http://poj.org/problem?id=1723 题解 带权中位数类型的题目~ 可以先考虑降维,最后集合的y坐标,明显是y坐标的中位数的位置,容易求出y方向的贡献res_y.比较麻烦的是在x坐标上最后是要列成一排,而不是单独的一个点,我们可以假设最后集合的最左边的点是x,采用贪心的策略列出公式:res_x=sum(abs(xi-x-i))(i belongs to [0,n-1]).令zi=xi-i,就转化为res_x=sum(abs(zi-x)),这相当于求zi数列的中位数(

带权中位数

话说在3085年,外星人打算来入侵地球,这个消息被我国的情报部门秘密截获,于是便打算联系世界各个国家,一 起研究商量对策.由于每个国家所需派的技术员人数不同,所以目前无法决定到底要在哪个国家设置个研究所进行 研究,幸运的是所有国家都在一条直线上,现在知道每个国家与我国的距离和该国的研究员人数.请你为他们决定 一下到底在那个国家建立研究所可以使所有研究员集中到该国的费用最小. Input 输入文件每一行描述一个国家的信息. 首先是该国派出的技术员人数,紧跟着的是这个城市相对于我国的距离,最后是国家

【poj 1988】Cube Stacking(图论--带权并查集 模版题)

题意:有N个方块,M个操作{“C x”:查询方块x上的方块数:“M x y”:移动方块x所在的整个方块堆到方块y所在的整个方块堆之上}.输出相应的答案. 解法:带权并查集.每堆方块作为一个集合,维护3个数组:fa[x]表示x方块所在堆的最顶部的方块:d[x]表示x方块所在堆的最底部的方块:f[x]表示x方块方块x上的方块数. 1 #include<cstdio> 2 #include<cstdlib> 3 #include<cstring> 4 #include<

2017 ACM/ICPC 新疆赛区 I 题 A Possible Tree 带权并查集

传送门 题意:给定一棵带权树的形态, 但是并不知道每天条边的具体权重. 然后给m个信息, 信息格式为u v val, 表示在树上u 到 v 的路径上经过的边的权重的异或和为val, 问前面最多有多少个信息是不冲突的. 思路:首先很明显的我们要维护一系列不知道的信息, 看冲不冲突的那就是带权并查集没跑了, 此时r[v] 表示v到这棵树的根节点(虽然题目没给, 但是我们可以假设一个)的路径异或和, 那么此时的每条信息相当于是告诉你r[u] ^ r[v]的值, 注意异或的特性. 所以对于每条信息维护好

并查集练习2(带权并查集)

明天旅游去爬山逛庙玩,今天练一天然后早早睡觉啦~ poj1703 Find them, Catch them (带权并查集) 1 #include<cstdio> 2 const int N=1e5+1; 3 int f[N]; 4 int r[N];//表示与父节点的关系,0同类,1不同类 5 int n; 6 void init(){ 7 for(int i=1;i<=n;++i){ 8 f[i]=i; r[i]=0; 9 } 10 } 11 int fin(int x){ 12 i

hdu 1558 Segment set【基础带权并查集+计算几何】

Segment set Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 3599    Accepted Submission(s): 1346 Problem Description A segment and all segments which are connected with it compose a segment set