题目:https://www.cometoj.com/contest/59/problem/F?problem_id=2681c++
题意:给你n个三元组 ai,bi,ci,若是某一对三元组知足 2*min(ai+aj,bi+bj) <= max(ai+aj,bi+bj),那么贡献+ci*cjspa
思路:咱们能够看的出这个式子其实就是说这个的最大值要是最小值的两倍,可是咱们不肯定哪一个大指针
咱们就先假设code
2*(ai+aj)<= bi+bjblog
移项得排序
(2*ai-bi)+(2*aj-bj)<=0ci
那么咱们按2*ai-bi排序get
咱们能够得出一个结论,若是当咱们得i与j匹配时,i一定和[i+1,j]都匹配,那么咱们这里就能够记录一个前缀和,那么i+1 也一定 是在[i+1,j]这个范围内找到匹配,it
因此咱们能够用两个指针进行查找,这是 ai+aj<=bi+bj的状况,>的时候咱们只要把ai与bi交换一下就能够了class
#include<bits/stdc++.h> #define maxn 100005 #define mod 1000000007 using namespace std; typedef long long ll; struct sss { ll a,b,c; }q[maxn]; ll num[maxn]; int n; int cmp(struct sss x,struct sss y) { return (2*x.a-x.b)<(2*y.a-y.b); } ll solve(){ sort(q,q+n,cmp); ll sum=0; int l=0,r=n-1; num[0]=q[0].c; for(int i=1;i<n;i++) num[i]=num[i-1]+q[i].c; while(r>=0){ ll t1=2*q[l].a-q[l].b; ll t2=2*q[r].a-q[r].b; if(t1+t2<=0) break; r--; } while(l<=r&&l<n&&r>=0){ sum=(sum+(num[r]-num[l-1])*q[l].c)%mod; l++; while(r>=0){ ll t1=2*q[l].a-q[l].b; ll t2=2*q[r].a-q[r].b; if(t1+t2<=0) break; r--; } } return sum; } int main(){ scanf("%d",&n); for(int i=0;i<n;i++){ scanf("%lld%lld%lld",&q[i].a,&q[i].b,&q[i].c); } ll sum=solve(); //printf("%lld\n",sum); for(int i=0;i<n;i++) swap(q[i].a,q[i].b); sum=(sum+solve())%mod; printf("%lld\n",sum); }