题意:

给你一个C,再给你n组a,b,让你求x取什么值的时候,$ \sum_{i=1}^n |a_i*x+b_i| =C $,要求求出解的个数,并用最简分数从小到大表示,如果有无穷多解,输出-1.

题解:

其实这些方程就是在平面上的一组曲线,都是V形的,最低点都在x轴上,求出所有的零点,以这个零点从左到右排序。

容易看出,这些函数之和也是一条曲线y=f(i),这条曲线最多有n个转折点,就是刚才那些零点,那么就在这n个转折点分出的n+1个区间内,和这n个点上,用比例公式找和y=C的交点即可。无穷多解的情况是存在一条与y=C重合的线段。

首先预处理出f(i)上所有转折点的值,注意n的范围是1e5,因此不可能让你$O(n^2)$求每一点的值,其实,只需维护a与b的前缀和和后缀和,要求某点$x_k$时,将零点在此点左边的函数取正,零点在此点右边的的函数取反。

$(\sum_{i=1}^{k-1}a_i) *x_k+\sum_{i=1}^{k-1}b_i-(\sum_{i=k+1}^{n}a_i) *x_k-\sum_{i=k+1}^{n}b_i$

注意判断零点重合情况。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<string>
#include<stack>
#include<algorithm>
using namespace std;
typedef long long LL;
typedef long long ll;
const int M = 1e5 + ;
const double eps = 1e-;
const LL mod = ;
const LL lINF = 0x3f3f3f3f3f3f3f3f;
struct node {
int a, b;
}tr[M];
int t;
int n, c;
int fenzi[M], fenmu[M];
int ans;
int gcd(int a, int b)
{
if (!b)
return a;
else
return gcd(b, a % b);
}
double lst;
bool cmp(node x, node y)
{
return x.a * y.b - x.b * y.a < ;
}
bool cmp2(node x, node y)
{
return (double)x.b / -x.a < (double)y.b / -y.a;
}
bool cmp1(node x, node y)
{
return (double)x.b / -x.a <= (double)y.b / -y.a;
}
int suma[M], sumb[M];
int flag;
double nw;
double nx;
int main()
{
scanf("%d", &t);
while (t--)
{
scanf("%d%d", &n, &c);
for (int i = ; i <= n; i++)
{
scanf("%d%d", &tr[i].a, &tr[i].b);
}
sort(tr + , tr + n + , cmp);
suma[] = sumb[] = ;
for (int i = ; i <= n; i++)
{
suma[i] = suma[i - ] + tr[i].a;
sumb[i] = sumb[i - ] + tr[i].b;
}
flag = ans = ;
lst = -10000.0;
for (int i = ; i <= n; i++)
{
int tmpa = -suma[n];
int tmpb = -sumb[n];
tmpa += * suma[i];
tmpb += * sumb[i];
nw = (double)sumb[i] / suma[i];
nx = (double)sumb[i + ] / suma[i + ];
if (fabs(nw - nx) < eps)
continue;
if (!tmpa && tmpb == c)
{
flag = ;
break;
}
if (!i)
{
node tmpc;
tmpc.a = tmpa, tmpc.b = tmpb - c;
if (cmp1(tmpc, tr[]))
{
fenzi[ans] = -tmpc.b;
fenmu[ans] = tmpa;
int d = gcd(fenzi[ans], fenmu[ans]);
fenzi[ans] /= d;
fenmu[ans] /= d;
if (fenmu[ans] < )
{
fenzi[ans] = -fenzi[ans], fenmu[ans] = -fenmu[ans];
}
ans++;
}
}
else if (i == n)
{
node tmpc;
tmpc.a = tmpa, tmpc.b = tmpb - c;
if (cmp2(tr[n], tmpc))
{
fenzi[ans] = -tmpc.b;
fenmu[ans] = tmpa;
int d = gcd(fenzi[ans], fenmu[ans]);
fenzi[ans] /= d;
fenmu[ans] /= d;
if (fenmu[ans] < )
{
fenzi[ans] = -fenzi[ans], fenmu[ans] = -fenmu[ans];
}
ans++;
}
}
else
{
node tmpc;
tmpc.a = tmpa, tmpc.b = tmpb - c;
if (cmp2(tr[i], tmpc) && cmp1(tmpc, tr[i + ]))
{
fenzi[ans] = -tmpc.b;
fenmu[ans] = tmpa;
int d = gcd(fenzi[ans], fenmu[ans]);
fenzi[ans] /= d;
fenmu[ans] /= d;
if (fenmu[ans] < )
{
fenzi[ans] = -fenzi[ans], fenmu[ans] = -fenmu[ans];
}
ans++;
}
}
lst = (double)(tmpb - c) / tmpa;
}
if (flag)
{
printf("-1\n");
}
else
{
printf("%d", ans);
for (int i = ; i < ans; i++)
{
printf(" %d/%d", fenzi[i], fenmu[i]);
}
puts("");
}
}
}

最新文章

  1. ASP.NET SignalR 高可用设计
  2. java自定义类加载器
  3. String和Date、Timestamp之间的转换
  4. Elasticsearch 运维实战之1 -- 集群规划
  5. bhrs报表年结步骤
  6. Express 4.x Node.js的Web框架
  7. CentOS 安装jdk7
  8. OpenRisc-50-or1200的freeze模块分析
  9. TortoiseGit客户端密钥配置
  10. vmware卸载问题
  11. 查看主机DNSserver
  12. Tomcat系统架构分析
  13. AbstractQueuedSynchronizer源码解读
  14. spring-cloud-Zuul学习(四)【中级】--自定义zuul Filter详解【重新定义spring cloud实践】
  15. MySQL游标循环取出空值的BUG
  16. 数据分析之Pandas
  17. 运维yum语法
  18. 解决Ubuntu自带编译器不好使问题
  19. Jira配置openLdap服务器进行用户认证
  20. python 图片相似度

热门文章

  1. snaker配置
  2. Python 多线程同步队列模型
  3. 在linux服务器中网站环境搭建好了.能看到首页,其他页面404解决
  4. 结合Intel Manual和libdasm学习汇编指令
  5. HDU 6590 Code (判断凸包相交)
  6. 拾遗:Qemu/KVM
  7. 剑指offer——68队列的最大值
  8. 前端(二十)—— vue介绍:引用vue、vue实例、实例生命周期钩子
  9. mybatis执行test07测试类却显示test05测试类调用的sql语句出错
  10. NIO 源码分析(02-2) BIO 源码分析 Socket