トピックリンクhttp://acm.hdu.edu.cn/showproblem.php?pid=6627
問題は、N個の絶対値が線形方程式が与えられて置くそれらの合計をcに等しくなるようにXを見つけることを意図しています。
AX + B | |、除去、2つだけのケースAX + Bと-ax-B、xの値に応じて、すなわちXおよびb /大小関係を考慮して絶対値。
N方程式とxの範囲は、方程式xが異なる範囲をとるときに、絶対値は、+ 1の場合、nの合計を除去するために変更され、1区間に分割N +します。
xはそれぞれ間隔をとり、N + 1個の異なる一次方程式に対応し、そして次いで直接必要な範囲内の間隔を解決するかどうかを決定するように、記載-a / bビットシーケンスを考えて排出します。
詳細の際にいくつかについての判断を注意してください。
#include <ビット/ STDC ++ H> のtypedef 長い 長LL。 使用して 名前空間はstdを、 CONSTの INT N = 1E5 + 5 。 constの LL MOD = 998244353 ; LLのC; int型のn; 構造体ノード { LL、B。 }。 ブールCMP(ノードX、ノードY) { 戻り XA * YB <XB * YA。 } ブールCMP2(ノードX、ノードY) { 戻り XA * YB == XB * YA。 } ノードF [N]。 ノードANS [N]。 int型のk; int型メイン() { int型のT。 scanf関数(" %のD "、&T)。 一方、(t-- ) { memsetの(F、0、はsizeof F)。 K = 0 。 scanf関数(" %Dの%のLLD "、&N、&C)。 LLスマ = 0、SUMB = 0 。 以下のために(int型 i = 1 ; iが++; iが<= N ) { scanf関数(" %のLLDの%のLLD "、&Fを[I] .A、&F [i]は.B)。 もし(F [i]が.A < 0 ) { スマ + = F [i]は.A。 SUMB + = F [i]は.B。 } 他 { スマ - = F [i]は.A。 SUMB - = F [i]は.B。 } } // coutの<<須磨<<」「<< SUMB <<てendl; ソート(F + 1、F + 1 + N、CMP)。 int型 FF = 0 ; 以下のための(int型 I = 0; iが<= N; iは++ ) { スマ + = 2 *のF [i]は.A。 SUMB + = 2 *のF [i]は.B。 もし(スマの== 0 && SUMB == C) { FF = 1 。 破ります; } LL X = C- SUMB。 LLのY = スマ。 もし(Y < 0 ) { Y * = - 1 。 バツ* = - 1 ; } LL G = __gcd(ABS(X)、Y); もし((x * fが[I + 1 ] .A <= - F [I + 1 ]の.B *のY)&&(F [i]が.A * X> = - [I] .B * F Y)) ANS [ ++ K] = {X / G、Y / G}。 } であれば(FF) { のprintf(" -1の\ n " ); 続け; } K =ユニーク(ANS + 1、ANS + 1 + K、CMP2)-ans- 1 。 printf(" %d個"、K)。 用(int型 iは= 1 ; iが= Kを<Iは++ ) { のprintf(" %LLD /%LLD " 、ANS [I] .A、ANS [I] .B)。 }プット("" )。 } 戻り 0 。 }