题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6627
题意:
给定n,c求x的所有解,输出其分数形式,如果有无数个解输出-1
题解:画出这n个绝对值函数的图像,发现它们的零点把x轴分成了n+1个区域,每个区域上都会有某个函数是原函数(绝对值符号里的那个函数)取负的形式,所以预处理一下ai,bi的负前缀和、正后缀和,可以直接得到每个区域上具体的一次方程,解方程判断解否在该区间内就可以了,如果存在a==0且b==c的情况那就是无数解了。
代码:
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int maxn = 1e5+5;
ll prea[maxn], preb[maxn], sufa[maxn], sufb[maxn];
struct fenshu{
ll z1, z2;
}ans[maxn];
struct node{
ll a, b;
fenshu z;
node(ll k1 = 0, ll k2 = 0, ll k3 = 0, ll k4 = 0){a = k1, b = k2, z.z1 = k3, z.z2 = k4;}
}d[maxn];
int cmp(fenshu A, fenshu B){
ll a1 = A.z1*B.z2, a2 = A.z2*B.z1;
if(a1 < a2) return -1;
else if(a1 == a2) return 0;
else return 1;
}
bool cmp2(node A, node B){
return cmp(A.z, B.z) < 0;
}
int main(){
int T;
scanf("%d", &T);
while(T--){
int n, c;
scanf("%d%d", &n, &c);
for(int i = 1; i <= n; i++){
scanf("%lld%lld", &d[i].a, &d[i].b);
if(d[i].a == 0){
d[i].z.z1 = 0;
d[i].z.z2 = 1;
}
else{
ll tmp = __gcd(d[i].a, -d[i].b);
d[i].z.z1 = -d[i].b/tmp;
d[i].z.z2 = d[i].a/tmp;
if(d[i].z.z2 < 0){
d[i].z.z2 = -d[i].z.z2;
d[i].z.z1 = -d[i].z.z1;
}
}
}
sort(d+1, d+n+1, cmp2);
prea[0] = preb[0] = 0;
sufa[n+1] = sufb[n+1] = 0;
for(int i = 1; i <= n; i++){
prea[i] = prea[i-1]+d[i].a;
preb[i] = preb[i-1]+d[i].b;
}
for(int i = n; i >= 1; i--){
sufa[i] = sufa[i+1]-d[i].a;
sufb[i] = sufb[i+1]-d[i].b;
}
bool flag = false;
ll cnt = 0;
for(int i = 0; i <= n; i++){
ll a = prea[i]+sufa[i+1];
ll b = preb[i]+sufb[i+1];
if(a == 0){
if(b == c){
flag = true;
break;
}
}
else{
fenshu temp;
ll tmp = __gcd(c-b, a);
temp.z1 = (c-b)/tmp;
temp.z2 = a/tmp;
if(temp.z2 < 0){
temp.z2 = -temp.z2;
temp.z1 = -temp.z1;
}
if(i == 0){
if(cmp(temp, d[i+1].z) <= 0) ans[cnt++] = temp;
}
else if(i == n){
if(cmp(temp, d[i].z) > 0) ans[cnt++] = temp;
}
else{
if(cmp(temp, d[i].z) > 0 && cmp(temp, d[i+1].z) <= 0) ans[cnt++] = temp;
}
}
}
if(flag){
printf("-1\n");
}
else{
printf("%d", cnt);
if(cnt != 0) printf(" ");
for(int i = 0; i < cnt; i++){
printf("%lld", ans[i].z1);
printf("/");
printf("%lld", ans[i].z2);
if(i != cnt-1) printf(" ");
}
printf("\n");
}
}
}