noip2014Day2T3解方程

来源:互联网 发布:三菱触摸屏软件 编辑:程序博客网 时间:2024/05/29 03:17

理论上70分

将a[i]模一个大质数,然后O(nm)

p=10^7+7比较科学

program ttt;const p=10000007;var n,v,j,m,t,i,ss:longint;    a:array[0..100]of longint;c:array[1..100000]of longint;procedure readdata(i:longint);var s:int64;    ch:char;begin s:=0; read(ch); if ch='-' then   begin    a[i]:=-1;   read(ch);  end else  a[i]:=1; while (ch>='0')and(ch<='9') do   begin    s:=(s*10+(ord(ch)-48)) mod p;   read(ch);  end; a[i]:=a[i]*s; readln;end;  begin readln(n,m); for i:=0 to n do  readdata(i); for i:=1 to m do  begin   v:=a[n];   for j:=n-1 downto 0 do    v:=(v*i+a[j]) mod p;//秦九韶算法   if v=0 then     begin ss:=ss+1; c[ss]:=i;end;  end; writeln(ss); for i:=1 to ss do  writeln(c[i]); readln;readln;end.


筛法

100分:

f(x+p)=f(x)+T

p|T

∴f(x+p)≡f(x) (mod p)

有周期性

所以可以选取几个小一点的质数检查x

同样注意使用int64
program ttt;const p:array[1..10]of longint=(1007,10007,12347,12349,100017,111647,19720308,19750920,19981117,20150208);var n,kk,j,m,i,ss:longint;t,v:int64;    a:array[0..100,1..10]of int64;inner:array[1..1000000]of boolean;c:array[1..1000000]of longint;procedure readdata(i:longint);var s:array[1..10]of int64;    ch:char;begin fillchar(s,sizeof(s),0); read(ch); if ch='-' then   begin    for kk:=1 to 10 do a[i][kk]:=-1;   read(ch);  end else  for kk:=1 to 10 do a[i][kk]:=1; while (ch>='0')and(ch<='9') do   begin    for kk:=1 to 10 do     s[kk]:=(s[kk]*10+(ord(ch)-48)) mod p[kk];   read(ch);  end; for kk:=1 to 10 do a[i][kk]:=a[i][kk]*s[kk]; readln;end; function check2(i,kk:longint):boolean;var t,j:longint;v:int64;begin v:=a[n][kk]; for j:=n-1 downto 0 do  v:=(v*i+a[j][kk]) mod p[kk]; if v<>0 then//不符合条件时才筛   begin   t:=i;   while t<=m do    begin inner[t]:=false; t:=t+p[kk];end;   exit(false);  end else  exit(true);end;function check(i:longint):boolean;var j:longint;begin if inner[i]=false then exit(false);//筛法 for j:=1 to 10 do//选取10个质数  if check2(i,j)=false then exit(false); exit(true);end;  begin readln(n,m); for i:=0 to n do  readdata(i); //a[i,kk]表示ai mod p[kk] fillchar(inner,sizeof(inner),true); for i:=1 to m do //每一个数每一个数检查  begin   if check(i) then     begin ss:=ss+1; c[ss]:=i;end;  end; writeln(ss); for i:=1 to ss do  writeln(c[i]); readln;readln;end.



0 0
原创粉丝点击