2742: [HEOI2012]Akai的数学作业

Description

 
这里是广袤无垠的宇宙这里是一泻千里的银河
这里是独一无二的太阳系
这里是蔚蓝色的地球
这里,就是这里,是富饶的中国大陆!
这里是神奇的河北大地
这里是美丽的唐山
这里是神话般的唐山一中
这里是Akai曾经的教室
黑板上还留有当年Akai做过的数学作业,其实也并不是什么很困难的题目:
给出一个一元n次方程:
a0 + a1x + a    2   x2 +…+ anxn= 0
求此方程的所有有理数解。

 

 ” Akai至今还深刻记得当年熬夜奋战求解的时光
他甚至还能记得浪费了多少草稿纸
但是却怎么也想不起来最后的答案是多少了
你能帮助他么?

Input

第一行一个整数n。第二行n+1个整数,分别代表a    0 到a n

Output

第一行输出一个整数t,表示有理数解的个数
接下来t行,每行表示一个解
解以分数的形式输出,要求分子和分母互质,且分母必须是正整数特殊的,如果这个解是一个整数,那么直接把这个数输出
等价的解只需要输出一次
所有解按照从小到大的顺序输出

Sample Input

3
-24 14 29 6

Sample Output

3
-4
-3/2
2/3

HINT

 

【数据范围】

对于30%的数据,n<=10 

对于100%的数据,n <= 100,|a i| <= 2*10^7,an≠ 0

Mogical Mathematics

好像是求$f(x) = a_0 + a_1x + a_2x^2 + … + a_nx^n$ 的零点

我们可以发现(有理数域下)式子一定可以变成 $g(x) * \Pi(b_ix + c_i)$

所以根就是$-\frac{c_i}{b_i}$

然后听说今天早上CMO大爷给我们证了一下$c_i$一定是$a_0$因数,$b_i$一定是$a_n$因数,具体是这样的:式子其实在复数域下是$\Pi(b_ix + c_i)$,然后所有$b_i$的积就是$x_n$的系数($a_n$),所有$c_i$的积就是常数项的系数($a_0$)

然后,我们就可以求出$a_n$、$a_0$所有因数,然后大力check一下就好啦。具体怎么check呢,就是代回去算23333(模意义下)

然后我就滚去写代码了QAQ

然后调不出来了QAQ,求教

 

 1 #include <bits/stdc++.h>
 2 #define LL long long
 3 using namespace std;
 4 int rt,op,x,l,r,t,L,R,d[6000005][30],s[6000005],m,X,Y,H[31],a[400005],b[6000000][2],w[30][400005]; LL ans;
 5 void add(int &u,int x,int h){
 6     if (!u) u=++t; ++s[u];
 7     for (int i=0;i<30;++i) d[u][i]+=bool(H[i]&x);
 8     if (~h) add(b[u][bool(H[h]&x)],x,h-1);
 9 }
10 LL ball(int u){
11     if (!u) return 0; LL w=0;
12     for (int i=0;i<30;++i) w+=1LL*H[i]*(X&H[i]?s[u]-d[u][i]:d[u][i]);
13     return w;
14 }
15 LL get(int u,int h,int k){
16     if (!k) return 0;
17     if (h<0) return ball()
18     if (Y&H[h]){
19         if (k<s[b[u][1]]) return get(b[u][1],h-1,k);
20         else return get(b[u][0],h-1,k-s[b[u][1]])+ball(b[u][1]);
21     }else{
22         if (k<s[b[u][0]]) return get(b[u][0],h-1,k);
23         else return get(b[u][1],h-1,k-s[b[u][0]])+ball(b[u][0]);
24     }
25 }
26 int main(){
27     scanf("%d%d",&R,&m); L=rt=t=1;
28     H[0]=1; for (int i=1;i<31;++i) H[i]=H[i-1]<<1;
29     for (int i=1;i<=R;++i) scanf("%d",&a[i]);
30     for (int i=0;i<30;++i)
31     for (int j=1;j<=R;++j) w[i][j]=w[i][j-1]+(bool)(a[j]&H[i]);
32     for (int i=1;i<=m;++i){
33         scanf("%d",&op);
34         if (op==1){
35             scanf("%d",&x); x^=X; a[++R]=x;
36             for (int j=0;j<30;++j) w[j][R]=w[j][R-1]+(bool)(x&H[j]);
37         }else
38         if (op==2){
39             scanf("%d%d",&l,&r); ans=0;
40             if (r>=L){
41                 x=max(l,L)-1;
42                 for (int j=0;j<30;++j) ans+=1LL*H[j]*(X&H[j]?r-x-w[j][r]+w[j][x]:w[j][r]-w[j][x]);
43             }
44             if (l<L) {
45                 x=min(L-1,r);
46                 ans+=(x==L-1?ball(1):get(1,29,x))-get(1,29,l-1);
47             }
48             printf("%lld\n",ans);
49         }else
50         if (op==3){
51             scanf("%d",&x); X^=x;
52         }else{
53             while (L<=R) add(rt,a[L++],29);
54             Y=X;
55         }
56     }
57     return 0;
58 }
View Code

 

posted @ 2017-07-04 18:27  xc01  阅读(189)  评论(2编辑  收藏  举报