[bzoj3378][Usaco2004 Open]MooFest 狂欢节_树状数组

MooFest 狂欢节 bzoj-3378 Usaco-2004 Open

题目大意:给定一个n个数的a序列,每两个数之间有一个距离,两个点之间的权值为$max(a[i],a[j])*dis(i,j)$。

注释:$1\le n\le 2\cdot 10^4$。



想法:裙子说了,这种$max$和$min$的题通常要枚举这个$max$和$min$到底是多少。

这样的话我们就将所有点按权值从大到小排序。

往树状数组里插。

查询直接查询即可。

最后,附上丑陋的代码... ...

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int N=20000;
int n,num[N+5],cnt;
long long sum[N+5],ans,tot;
struct Node{int v,x;}a[N+5]; bool cmp(const Node &x,const Node &y){return x.v>y.v;}
inline int lowbit(int x) {return x&(-x);}
void add(int x,int v,int k)
{
    for(int i=x;i<=N;i+=lowbit(i))
        sum[i]+=v,num[i]+=k;
}
void query(int x)
{
    for(int i=x;i>0;i-=lowbit(i))
        tot+=sum[i],cnt+=num[i];
}
void work()
{
    for(int i=1;i<=n;i++)
	{
        tot=cnt=0;
        query(a[i].x);
        ans+=a[i].v*(cnt*a[i].x-tot);
        cnt=-cnt,tot=-tot;
        query(N);
        ans+=a[i].v*(tot-cnt*a[i].x);
        add(a[i].x,-a[i].x,-1);
    }
    cout << ans << endl ;
}
void init()
{
    cin >> n ;
    for(int i=1;i<=n;i++) scanf("%d%d",&a[i].v,&a[i].x);
    sort(a+1,a+1+n,cmp);
    for(int i=1;i<=n;i++) add(a[i].x,a[i].x,1);
}
int main()
{
    init();
    work();
    return 0;
}

小结:裙子有时候想法好$nb$啊!%%%

原文地址:https://www.cnblogs.com/ShuraK/p/9551668.html

时间: 2024-10-10 08:45:49

[bzoj3378][Usaco2004 Open]MooFest 狂欢节_树状数组的相关文章

[BZOJ3378] [Usaco2004 Open]MooFest 狂欢节(树状数组)

传送门 开2个树状数组 一个存的是下标,一个存的是数量 细节...看标称吧,懒得说了,好气啊 #include <cstdio> #include <iostream> #include <algorithm> #define N 20001 #define LL long long #define max(x, y) ((x) > (y) ? (x) : (y)) int n, m; LL ans, sum, c[N], d[N]; struct node {

bzoj3378[Usaco2004 Open]MooFest 狂欢节*

bzoj3378[Usaco2004 Open]MooFest 狂欢节 题意: n只奶牛,第i只听力为vi,坐标为xi,两只奶牛聊天时音量是max(vi,vj)*abs(xi-xj).求n(n-1)/2对奶牛的音量和.n≤20000. 题解: 首先所有奶牛按x排序,记录其位置,接着再按它们音量升序排序依次插入树状数组.维护两个树状数组,一个用来求位置比某奶牛大的坐标和和奶牛数,另一个用来求位置比某奶牛小的坐标和和奶牛数.对于每个插入的奶牛i,对答案的贡献是vi*位置比它大的坐标和与奶牛数*该奶牛

MooFest POJ - 1990 (树状数组)

Every year, Farmer John's N (1 <= N <= 20,000) cows attend "MooFest",a social gathering of cows from around the world. MooFest involves a variety of events including haybale stacking, fence jumping, pin the tail on the farmer, and of cours

See you~_树状数组

Problem Description Now I am leaving hust acm. In the past two and half years, I learned so many knowledge about Algorithm and Programming, and I met so many good friends. I want to say sorry to Mr, Yin, I must leave now ~~>.<~~. I am very sorry, we

BZOJ_3653_谈笑风生_树状数组

Description 设T 为一棵有根树,我们做如下的定义: ? 设a和b为T 中的两个不同节点.如果a是b的祖先,那么称“a比b不知道 高明到哪里去了”. ? 设a 和 b 为 T 中的两个不同节点.如果 a 与 b 在树上的距离不超过某个给定 常数x,那么称“a 与b 谈笑风生”. 给定一棵n个节点的有根树T,节点的编号为1 到 n,根节点为1号节点.你需 要回答q 个询问,询问给定两个整数p和k,问有多少个有序三元组(a;b;c)满足: 1. a.b和 c为 T 中三个不同的点,且 a为

BZOJ_5055_膜法师_树状数组+离散化

Description 在经历过1e9次大型战争后的宇宙中现在还剩下n个完美维度, 现在来自多元宇宙的膜法师,想偷取其中的三个维度为伟大的长者续秒, 显然,他能为长者所续的时间,为这三个维度上能量的乘积, 但目前的宇宙很不乐观,胡乱偷取可能造成维度的崩溃, 所以,他必须按逆序偷取这些维度,且在偷取中, 每次偷取的维度的能量必须严格小于他上次偷取的能量, 由于膜法师生活在多元宇宙,所以他可以让所有可能的偷取方案全部发生 题目描述 但他数学不好,所以找到了你帮他求出能为长者续几秒, 你要做的,就是在

[bzoj2131]免费的馅饼_树状数组

免费的馅饼 bzoj-2131 题目大意: 注释:$1\le n \le 10^5$,$1\le w \le 10^8$. 想法:首先,想到dp 状态:dp[i][j]表示i分钟在位置j的最大收益 优化优化 状态:dp[i]表示最后收到i的最大收益. 转移:顺序枚举i:1->n即可. 然后,我们尝试优化 对于这个状态我们会发现转移的时候有一个绝对值的死东西,我们将它拆开就有: 2*t[j]+pos[j]<=2*t[i]+pos[i]且2*t[j]-pos[j]<=2*t[i]-pos[i

[bzoj3529][Sdoi2014]数表_树状数组_莫比乌斯反演

数表 bzoj-3529 Sdoi-2014 题目大意:n*m的数表,第i行第j列的数是同时整除i和j的所有自然数之和.给定a,求数表中所有不超过a的和. 注释:$1\le n,m \le 10^5$. 想法:我们先不考虑那个a的限制:我们设f(i)表示整除i的自然数之和. $\sum\limits_{i=1}^n\sum\limits_{j=1}^m f(gcd(i,j))$ $\sum\limits_{i=1}^n\sum\limits_{j=1}^m f(d)\cdot [gcd(i,j)

[bzoj1103][POI2007]大都市meg_dfs序_树状数组

大都市meg bzoj-1103 POI-2007 题目大意:给定一颗n个点的树,m次操作.将一条路的边权更改成0:查询一个点到根节点的点权和.开始的时候所有边的边权都是1. 注释:$1\le n,m\le 2.5\cdot 10^5$. 想法:我们先拉出dfs序.其实严格来讲是出栈入栈序,就是每个点在序上出现两次的那个. 开始的时候入栈时的点权是1,出栈是-1.修改就是把出栈入栈都改成0.然后用树状数组查询前缀和即可. 最后,附上丑陋的代码... ... #include <iostream>