题意:,给你c和n个ai,bi,让你求出x的所有解
题解:因为每个式子如果小于0即再取绝对值就相当于取个负号,所以每个区间内的式子正负都是决定好的,直接求每个区间内的x即可
思路倒是好理解,代码比较难写,我的代码借鉴了这里 ,具体讲一下代码怎么写的吧,首先按照-bi/ai的大小排序
然后把所有的ka=-∑ai,kb=-∑bi,相当于所有的都是负的情况,然后不停的对ka+=2*ai,kb+=2*bi说明前几个是正的后面全是负的
如果中间出现了ka==0,kb==c的情况说明x有无限个情况,直接-1,取完所有的值之后别忘了去重,我这里重载的==号就可以用unique函数了(代码真的妙啊ORz)
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
#define mem(s) memset(s, 0, sizeof(s))
const int INF = 0x3f3f3f3f;
const double eps = 1e-8;
const int maxn = 1e6+5;
const int mod = 998244353;
struct node {
ll a,b;
bool operator ==(const node &rhs)const{
if(a==rhs.a&&b==rhs.b)return 1;
else return 0;
}
}ans[maxn],a[maxn];
int n,c;
bool cmp(node a,node b){
return a.b*b.a<b.b*a.a;
}
int main()
{
int t;
scanf("%d",&t);
while(t--){
int coun=0,flag=0;
memset(a,0,sizeof(a));
ll ka=0,kb=0;
scanf("%d%d",&n,&c);
for(int i=1;i<=n;i++){
scanf("%lld%lld",&a[i].a,&a[i].b);
ka-=a[i].a,kb-=a[i].b;
a[i].b*=-1;
}
sort(a+1,a+1+n,cmp);
for(int i=0;i<=n;i++){
ka+=2*a[i].a;
kb+=-2*a[i].b;
if(ka==0&&kb==c){
flag=1;
break;
}
ll bb=c-kb;
ll aa=ka;
if(aa<0){
aa*=-1;
bb*=-1;
}
ll g=__gcd(aa,abs(bb));
if(bb*a[i+1].a<=a[i+1].b*aa&&a[i].a*bb>=a[i].b*aa){
ans[++coun].a=aa/g;
ans[coun].b=bb/g;
}
}
if(flag){
printf("-1\n");
continue;
}
sort(ans+1,ans+1+coun,cmp);
coun=unique(ans+1,ans+1+coun)-(ans+1);
if(coun==0){
printf("0\n");
continue;
}
printf("%d ",coun);
for(int i=1;i<=coun;i++){
printf("%lld/%lld",ans[i].b,ans[i].a);
if(i==coun)printf("\n");
else printf(" ");
}
}
return 0;
}