标签:fine div 要求 using 元素 can cstring i++ 题意
题意:
一群牛参加完牛的节日后都有了不同程度的耳聋,第i头??听见别人的讲话,别牛??的音量必须大于v[i],当两头牛i,j交流的时候,交流的最小声音为max{v[i],v[j]}*他们之间的距离。现在有n头牛,求他们之间两两交流最少要的音量和。
拿到后很难入手 枚举n^2k肯定是超时的
可以根据所有牛的耳背程度从小到大排序 这样从头开始调用排序好的数据 只要求 当前牛到目前已遍历的所有牛的距离之和(分别处理当前牛左边的数量+右边的数量) 乘 当球牛的耳背程度(因为当球牛的耳背程度是最高的 所以无需考虑别的牛的耳背程度)
求和问题用树状数组来处理比较快
该题采用两个树状数组 一个为牛的数量 一个为牛的距离 !!
并且求所有元素两两的关系值得学习 只要一次遍历就可以了 不断求当前的与 之前 所有的即可
在结构体内部定义 比较函数 比cmp要快!!!!
#include<cstdio> #include<cstring> #include<algorithm> using namespace std; #define N 20005 struct node { long long x,v; bool operator<(const node &a)const { return v<a.v; } }s[N]; long long c[2][N]; int lowbit(int i) { return i&-i; } void update(int x,long long v,int d) { for(int i=x;i<N;i+=lowbit(i)) c[d][i]+=v; } long long sum(int x,int d) { long long ans=0; for(int i=x;i>0;i-=lowbit(i)) ans+=c[d][i]; return ans; } int main() { int n; scanf("%d",&n); memset(c,0,sizeof(c)); //memset(s,0,sizeof(s)); for(int i=1;i<=n;i++) { scanf("%lld%lld",&s[i].v,&s[i].x); } sort( s+1,s+n+1 ); long long ans=0,a,b; for(int i=1;i<=n;i++) { a=sum( s[i].x ,0 );//在此前牛左边的 牛的个数 b=sum ( s[i].x,1 );//此前牛左边 牛的距离和 ans+= ( a*s[i].x-b+ sum(20000,1)-b-(i-a-1)*s[i].x ) *s[i].v; update( s[i].x,1,0 ); update( s[i].x , s[i].x ,1); } printf("%lld\n",ans); return 0; }
标签:fine div 要求 using 元素 can cstring i++ 题意
原文地址:https://www.cnblogs.com/bxd123/p/10357669.html