HDU6627 equation
题目链接
题意:
两个长度为\(n\)的数组\(a\)和\(b\)和一个正整数\(C\),计算有多少个\(x\)满足:
\[\sum_{i=1}^n|a_i \cdot x+b_i|=C
\]
思路:
该函数为分段函数,每段的转折点为\(-\frac{b_i}{a_i}\),先把转折点排序,计最开始的函数值为\(x \cdot suma + sumb\),每过一段,就会有一个\(|a_i \cdot x+b_i|\)由\(a_i \cdot x+b_i\)变为\(-a_i \cdot x - b_i\),那么\(suma-2 \cdot a_i\),\(sum_b\)变为 \(sumb-2 \cdot b_i\)。每段函数都是线性的,大力枚举计算即可。然后对答案进行排序(博主忘记排序结果Wa到爆炸)。
代码:
#include<bits/stdc++.h>
using namespace std;
const int N = 2e5+100;
struct node{
long long a,b;
}s[N];
int n;double c;
bool cmp(node x,node y){
return (x.b*y.a)<(x.a*y.b);
}
bool cmp2(pair<long long, long long> a,pair<long long,long long> b){
return a.first*b.second<a.second*b.first;
}
vector<pair<long long,long long>> ans;
void make(long long x,long long y){
if(x==0){
y=1;
ans.push_back({x,y});return ;
}
long long gg=__gcd(x,y);
x/=gg;y/=gg;
if(y<=0){
x=-x;y=-y;
}
ans.push_back({x,y});
return ;
}
void solve(){
ans.clear();
scanf("%d %lf",&n,&c);
long long sa=0;long long sb=0;
for(int i=1;i<=n;i++){
scanf("%lld %lld",&s[i].a,&s[i].b);
sa+=s[i].a;
sb+=s[i].b;
}
sort(s+1,s+n+1,cmp);
double up=9999999999999;
double down=-1.0*double(s[1].b*sa)/double(s[1].a)+sb;
if(c>=down&&c<=up){
long long u=(long long)c-sb;
long long d=sa;
make(u,d);
}
bool flag=0;
for(int i=2;i<=n;i++){
double nowr=(-1.0*double(s[i].b)*(sa-2*s[i-1].a)/double(s[i].a))+(sb-2*s[i-1].b);
double bef=(-1.0*double(s[i-1].b)/double(s[i-1].a))*(sa)+(sb);
up=max(nowr,bef);
down=min(nowr,bef);
if(up==down&&up==c){
flag=1;break;
}
sa-=2*s[i-1].a;
sb-=2*s[i-1].b;
if(c>=down&&c<=up){
long long u=(long long)c-sb;
long long d=sa;
make(u,d);
}
}
sa-=2*s[n].a;
sb-=2*s[n].b;
up=9999999999999;
down=-1.0*double(s[n].b*sa)/double(s[n].a)+sb;
if(c>=down&&c<=up){
long long u=c-sb;
long long d=sa;
make(u,d);
}
if(flag) puts("-1");
else{
sort(ans.begin(),ans.end(),cmp2);
int siz=unique(ans.begin(),ans.end())-ans.begin();
printf("%d",siz);
for(int i=0;i<(int)siz;i++) printf(" %lld/%lld", ans[i].first,ans[i].second);
puts("");
}
}
int main(){
int T;scanf("%d",&T);
while(T--) solve();
return 0;
}
/*
2 6
0 4
-2 -6
*/