洛谷P4774 屠龙勇士

啊我死了。

肝了三天的毒瘤题......他们考场怎么A的啊。


大意:

给你若干个形如 的方程组,求最小整数解。

嗯......exCRT的变式。

考虑把前面的系数化掉:

然后就是exCRT板子了。

我TM想要自己写出一个板子,然后GG了......

我快疯了。

然后抄了板子(滑稽)

注意细节,快速幂/乘的时候,b位置不要传负数。

  1 #include <cstdio>
  2 #include <set>
  3 #include <algorithm>
  4 
  5 typedef long long LL;
  6 const int N = 100010;
  7 
  8 std::multiset<LL> S;
  9 std::multiset<LL>::iterator it;
 10 int n, m, Time, vis[N];
 11 LL a[N], p[N], awd[N], use[N];
 12 
 13 LL Val;
 14 LL gcd(LL a, LL b) {
 15     if(!b) {
 16         return a;
 17     }
 18     return gcd(b, a % b);
 19 }
 20 inline LL lcm(LL a, LL b) {
 21     return a / gcd(a, b) * b;
 22 }
 23 void exgcd(LL a, LL b, LL &x, LL &y) {
 24     if(!b) {
 25         x = Val / a;
 26         y = 0;
 27         return;
 28     }
 29     exgcd(b, a % b, x, y);
 30     std::swap(x, y);
 31     y -= (a / b) * x;
 32     return;
 33 }
 34 inline LL mod(LL a, LL c) {
 35     while(a >= c) {
 36         a -= c;
 37     }
 38     while(a < 0) {
 39         a += c;
 40     }
 41     return a;
 42 }
 43 inline LL mul(LL a, LL b, LL c) {
 44     LL ans = 0;
 45     a %= c;
 46     b %= c;
 47     while(b) {
 48         if(b & 1) {
 49             ans = mod(ans + a, c);
 50         }
 51         a = mod(a << 1, c);
 52         b = b >> 1;
 53     }
 54     return ans;
 55 }
 56 inline LL qpow(LL a, LL b, LL c) {
 57     LL ans = 1;
 58     a %= c;
 59     while(b) {
 60         if(b & 1) {
 61             ans = mul(ans, a, c);
 62         }
 63         a = mul(a, a, c);
 64         b = b >> 1;
 65     }
 66     return ans;
 67 }
 68 inline LL abs(LL a) {
 69     return a < 0 ? -a : a;
 70 }
 71 inline LL inv(LL a, LL c) {
 72     LL x, y;
 73     Val = 1;
 74     exgcd(a, c, x, y);
 75     return mod(x, c);
 76 }
 77 //----math----
 78 
 79 inline void solve_p1() {
 80     LL ans = 0;
 81     for(int i = 1; i <= n; i++) {
 82         LL temp = (a[i] - 1) / use[i] + 1;
 83         ans = std::max(ans, temp);
 84     }
 85     printf("%lld\n", ans);
 86     return;
 87 }
 88 
 89 inline void solve_n1() {
 90     LL g = gcd(use[1], p[1]);
 91     if(a[1] % g) {
 92         puts("-1");
 93         return;
 94     }
 95     LL x, y;
 96     Val = a[1];
 97     exgcd(use[1], p[1], x, y);
 98     // use[1] * x + p[1] * y == a[1]
 99     LL gap = (use[1] / g);
100     //printf("gap = %lld  y = %lld \n", gap, y);
101     LL yy = (y % gap - gap) % gap;
102     //printf("yy = %lld \n", yy);
103     LL dt = (y - yy) / gap;
104     //printf("dt = %lld \n", dt);
105     x += dt * (p[1] / g);
106     //printf("x = %lld \n", x);
107     printf("%lld\n", x);
108     return;
109 }
110 
111 inline void solve_a() {
112     LL large = 0;
113     for(int i = 1; i <= n; i++) {
114         large = std::max(large, (a[i] - 1) / use[i] + 1);
115         LL g = gcd(use[i], p[i]);
116         if(a[i] % g) {
117             puts("-1");
118             return;
119         }
120         if(p[i] == 1) {
121             vis[i] = Time;
122             continue;
123         }
124         //printf("%lld %lld %lld \n", use[i], p[i], a[i]);
125         a[i] /= g;
126         p[i] /= g;
127         use[i] /= g;
128         use[i] %= p[i];
129         a[i] %= p[i];
130         if(!use[i]) {
131             if(!a[i]) {
132                 vis[i] = Time;
133                 continue;
134             }
135             else {
136                 puts("-1");
137                 //printf("%lld %lld %lld \n", use[i], p[i], a[i]);
138                 return;
139             }
140         }
141         LL Inv, temp;
142         Val = 1;
143         exgcd(use[i], p[i], Inv, temp);
144         Inv = mod(Inv, p[i]);
145         //printf("Inv = %lld \n", Inv);
146         a[i] = mul(Inv, a[i], p[i]);
147     }
148     // x = a[i] (mod p[i])
149 
150     /*for(int i = 1; i <= n; i++) {
151         printf("x === %lld mod %lld \n", a[i], p[i]);
152     }*/
153 
154     bool fd = 0;
155     LL A = 0, P = 1;
156     for(int i = 1; i <= n; i++) {
157         //printf("%d \n", i);
158         if(vis[i] == Time) {
159             continue;
160         }
161         if(!fd) {
162             A = a[i];
163             P = p[i];
164             fd = 1;
165             continue;
166         }
167         // merge i
168         LL x, y;
169         LL C = ((a[i] - A) % p[i] + p[i]) % p[i];
170         LL g = gcd(P, p[i]);
171         if(C % g) {
172             puts("-1");
173             return;
174         }
175         Val = g;
176         exgcd(P, p[i], x, y);
177         x = mul(x, C / g, P / g * p[i]);
178         A += mul(x, P, P / g * p[i]);
179         P *= p[i] / g;
180         A = (A + P) % P;
181     }
182     // x = A (mod P)
183     // 1 * x + y * P = A
184 
185     LL x, y;
186     Val = A;
187     exgcd(1, P, x, y);
188     x = mod(x, P);
189     if(x < large) {
190         x += P * ((large - x - 1) / P + 1);
191     }
192     printf("%lld\n", x);
193     return;
194 }
195 
196 inline void solve() {
197     scanf("%d%d", &n, &m);
198     for(int i = 1; i <= n; i++) {
199         scanf("%lld", &a[i]);
200     }
201     for(int i = 1; i <= n; i++) {
202         scanf("%lld", &p[i]);
203     }
204     for(int i = 1; i <= n; i++) {
205         scanf("%lld", &awd[i]);
206     }
207     for(int i = 1; i <= m; i++) {
208         LL x;
209         scanf("%lld", &x);
210         S.insert(x);
211     }
212     for(int i = 1; i <= n; i++) {
213         it = S.upper_bound(a[i]);
214         if(it != S.begin()) {
215             it--;
216         }
217         use[i] = (*it);
218         S.erase(it);
219         S.insert(awd[i]);
220     }
221 
222     //-------------------- p = 1  30pts -------
223     bool f = 1;
224     for(int i = 1; i <= n; i++) {
225         if(p[i] > 1) {
226             f = 0;
227             break;
228         }
229     }
230     if(f) {
231         solve_p1();
232         return;
233     }
234 
235     //-------------------- n = 1  30pts -------
236     if(n == 1) {
237         solve_n1();
238         return;
239     }
240 
241     solve_a();
242     return;
243 }
244 
245 int main() {
246 
247     int T;
248     scanf("%d", &T);
249     for(Time = 1; Time <= T; Time++) {
250         solve();
251         if(Time < T) {
252             S.clear();
253         }
254     }
255 
256     return 0;
257 }
AC代码

一共提交了14次.......

posted @ 2018-11-29 16:03  huyufeifei  阅读(215)  评论(0编辑  收藏  举报
试着放一个广告栏(虽然没有一分钱广告费)

ReadEra 阅读书籍

『Flyable Heart 応援中!』 HHG 高苗京铃 闪十PSS 双六 電動伝奇堂 章鱼罐头制作组 はきか 祝姬 星降夜