NOIp2018集训test-10-20 (bike day6)

B 君的第一题 lanzhou

$x^{\frac{p-1}{2}}\equiv 1(mod\ p)$

$x\equiv x*x^{\frac{p-1}{2}} (mod\ p)$

$x\equiv x^{\frac{p+1}{2}} (mod\ p)$

$\sqrt{x}\equiv x^{\frac{p+1}{4}} (mod\ p)$

就成了一道快速幂的题了,然而唯二A了的我和李巨都是用类似复数快速幂那种方法暴力开根号。

我:这道题感觉没意义啊,会二次剩余的暴力开根也开出来了,不会的怎么都GG了。

李巨:没有啊,你只要会费马小定理这个题随便推吧。

(数学一窍不通—根本推不出来的)我:%%%

要是7个月前我会开根号的话现在我大概就不在这里了吧。

 1 //Achen
 2 #include<bits/stdc++.h>
 3 #define For(i,a,b) for(int i=(a);i<=(b);i++)
 4 #define Rep(i,a,b) for(int i=(a);i>=(b);i--)
 5 #define Formylove return 0
 6 const int p=1000000007,inv2=500000004,inv4=250000002;
 7 typedef long long LL;
 8 typedef double db;
 9 using namespace std;
10 int T;
11 LL b,c;
12 
13 template<typename T> void read(T &x) {
14     char ch=getchar(); x=0; T f=1;
15     while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar();
16     if(ch=='-') f=-1,ch=getchar();
17     for(;ch>='0'&&ch<='9';ch=getchar()) x=x*10+ch-'0'; x*=f;
18 }
19 
20 LL w;
21 struct fs {
22     LL a,b;
23     fs(){}
24     fs(LL a,LL b):a(a),b(b){}
25 };
26 
27 LL mo(LL x) { return x<0?x+p:(x>=p?x-p:x); }
28 
29 fs operator +(const fs&A,const fs&B) { return fs(mo(A.a+B.a),mo(A.b+B.b)); }
30 fs operator *(const fs&A,const fs&B) { return fs(mo(A.a*B.a%p+A.b*B.b%p*w%p),mo(A.a*B.b%p+A.b*B.a%p)); }
31 
32 LL fsksm(fs a,LL b) {
33     fs rs=fs(1,0),bs=a;
34     while(b) {
35         if(b&1) rs=rs*bs;
36         bs=bs*bs;
37         b>>=1;
38     }
39     return rs.a;
40 }
41 
42 LL ksm(LL a,LL b) {
43     LL bs=a%p,rs=1;
44     while(b) {
45         if(b&1) rs=rs*bs%p;
46         bs=bs*bs%p;
47         b>>=1;
48     }
49     return rs;
50 }
51 
52 int ck(LL x) { return ksm(x,(p-1)/2)==1; }
53 
54 LL get_sqr(LL x) {
55     LL a=rand()%p+1;
56     while(ck(mo(a*a%p-x))) {
57         a=rand()%p+1;
58     }
59     w=mo(a*a%p-x);
60     return fsksm(fs(a,1),(p+1)/2);
61 }
62 
63 #define ANS
64 int main() {
65 #ifdef ANS
66     freopen("lanzhou.in","r",stdin);
67     freopen("lanzhou.out","w",stdout);
68 #endif
69     srand(998244353);
70     read(T);
71     For(cs,1,T) {
72         read(b); read(c);
73         LL x=(b*b%p*inv4%p-c+p)%p;
74         if(!x) {
75             LL m1=b*inv2%p;
76             LL m2=mo(b-m1);
77             if(m1>m2) swap(m1,m2);
78             printf("%lld %lld\n",m1,m2);
79         }
80         else if(ck(x)) {
81             LL y=get_sqr(x);
82             LL m1=mo(y+b*inv2%p);
83             LL m2=mo(b-m1);
84             if(m1>m2) swap(m1,m2);
85             printf("%lld %lld\n",m1,m2);
86         }
87         else puts("-1 -1");
88     }
89     Formylove;
90 }
View Code

 

B 君的第二题 xining

Bike老爷专门卡kmp,成功卡掉了一个机房。

因为有退格操作,可能aaaaaaaab-b-b-b-b这样的数据就会一直跳,所以要把自动机建出来,也就是保存下每个位置选择a~z每个字母时会走到哪里。

同理AC自动机也是,sxy和llj的写法都是要补全儿子的,我以前那种不补全儿子的写法就可以被某些题卡。

 1 //Achen
 2 #include<bits/stdc++.h>
 3 #define For(i,a,b) for(int i=(a);i<=(b);i++)
 4 #define Rep(i,a,b) for(int i=(a);i>=(b);i--)
 5 #define Formylove return 0
 6 const int N=300007;
 7 typedef long long LL;
 8 typedef double db;
 9 using namespace std;
10 char s[N],op[N];
11 int nxt[N],n,ts[N][26];
12 
13 template<typename T> void read(T &x) {
14     char ch=getchar(); x=0; T f=1;
15     while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar();
16     if(ch=='-') f=-1,ch=getchar();
17     for(;ch>='0'&&ch<='9';ch=getchar()) x=x*10+ch-'0'; x*=f;
18 }
19 
20 #define ANS
21 int main() {
22 #ifdef ANS
23     freopen("xining.in","r",stdin);
24     freopen("xining.out","w",stdout);
25 #endif
26     memset(ts,-1,sizeof(ts));
27     scanf("%s",s);
28     scanf("%s",op);
29     int lena=strlen(s);
30     s[lena]='&';
31     memset(ts[0],0,sizeof(ts[0]));
32     for(int i=1,k=0;i<=lena;i++) {
33         For(x,0,25) {
34             if(x==s[k]-'a') ts[i][x]=k+1;
35             else if(!k) ts[i][x]=k;
36             else {
37                 if(x==s[nxt[k-1]]-'a') ts[i][x]=nxt[k-1]+1;
38                 else ts[i][x]=ts[nxt[k-1]][x];
39             }
40         }
41         k=ts[i][s[i]-'a'];
42         nxt[i]=k;
43     }
44     int leno=strlen(op);
45     int i=lena,k=0;
46     printf("%d\n",lena);
47     For(cs,0,leno-1) {
48         if(op[cs]=='-') {
49             if(i>lena) {
50                 nxt[i]=0;
51                 memset(ts[i+1],-1,sizeof(ts[i+1]));
52                 i--; 
53                 k=nxt[i];
54             }
55         }
56         else {
57             s[++i]=op[cs];
58             For(x,0,25) {
59                 if(x==s[k]-'a') ts[i][x]=k+1;
60                 else if(!k) ts[i][x]=k;
61                 else {
62                     if(x==s[nxt[k-1]]-'a') ts[i][x]=nxt[k-1]+1;
63                     else ts[i][x]=ts[nxt[k-1]][x];
64                 }
65             }
66             k=ts[i][op[cs]-'a'];
67             nxt[i]=k;
68         }
69         printf("%d\n",lena-nxt[i]);
70     }
71     Formylove;
72 }
73 /*
74 aaa
75 aaaaaaab-b-b-b-b-
76 */
View Code

 

B 君的第三题 yinchuan

ORZ哥德巴赫猜想,我对数学一窍不通还真是对不起了。(从小从没学过数竟,初中在贫困山区的破烂学校上的,再有名我都不知道)

首先区间操作想到差分,每个点表示它和它前面一个点是否相同。现在翻转一个区间变成了翻转两个点,最终使序列全为0。

一次翻转i,j两个点的代价:

|i-j|为奇质数:1

|i-j|为偶数(根据哥德巴赫猜想,大于等于6的偶数都能拆成两个奇质数之和,2=5-3,4=7-3):2

|i-j|为奇合数:3(先变成偶数再2次操作)

那么容易发现翻转0一定不优,每次都是翻转两个1,且1的个数一定为偶数。

那么把1的位置按奇偶分类,差的绝对值为奇质数的连边,二分图匹配。剩下的左边跟左边配右边跟右边配,最多左右各剩一个就左右配。

 1 //Achen
 2 #include<bits/stdc++.h>
 3 #define For(i,a,b) for(int i=(a);i<=(b);i++)
 4 #define Rep(i,a,b) for(int i=(a);i>=(b);i--)
 5 #define Formylove return 0
 6 const int N=107,up=10009;
 7 typedef long long LL;
 8 typedef double db;
 9 using namespace std;
10 int n,a[N],b[N],c[N],ans;
11 
12 template<typename T> void read(T &x) {
13     char ch=getchar(); x=0; T f=1;
14     while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar();
15     if(ch=='-') f=-1,ch=getchar();
16     for(;ch>='0'&&ch<='9';ch=getchar()) x=x*10+ch-'0'; x*=f;
17 }
18 
19 int bo[up+7],p[up+7];
20 void get_prime() {
21     For(i,2,up) {
22         if(!bo[i]) p[++p[0]]=i;
23         for(int j=1;j<=p[0]&&i*p[j]<=up;j++) {
24             bo[i*p[j]]=1;
25             if(i%p[j]==0) break;
26         }
27     }
28     bo[1]=bo[2]=1;
29 }
30 
31 void GM(LL &x,LL y) { if(x>y) x=y; }
32 
33 int vis[N],pr[N],mp[N][N];
34 int find(int x) {
35     For(i,1,c[0]) if(mp[x][i]&&!vis[i]) {
36         vis[i]=1;
37         if(!pr[i]||find(pr[i])) {
38             pr[i]=x;
39             return 1;
40         }
41     }
42     return 0;
43 }
44 
45 #define ANS
46 int main() {
47 #ifdef ANS
48     freopen("yinchuan.in","r",stdin);
49     freopen("yinchuan.out","w",stdout);
50 #endif
51     read(n);
52     get_prime();
53     For(i,1,n) read(a[i]);
54     For(i,1,n) {
55         if(i==1||a[i-1]!=a[i]-1) {
56             if(a[i]&1) b[++b[0]]=a[i];
57             else c[++c[0]]=a[i];
58         }
59         if(a[i+1]!=a[i]+1) {
60             if((a[i]+1)&1) b[++b[0]]=a[i]+1;
61             else c[++c[0]]=a[i]+1;
62         }
63     }
64     For(i,1,b[0]) For(j,1,c[0]) {
65         if(!bo[abs(b[i]-c[j])]) mp[i][j]=1;
66     }
67     For(i,1,b[0]) {
68         memset(vis,0,sizeof(vis));
69         ans+=find(i);
70     }
71        if((b[0]-ans)&1) ans=ans+(b[0]-ans)/2*2+(c[0]-ans)/2*2+3;
72        else ans=ans+(b[0]-ans)+(c[0]-ans);
73     printf("%d\n",ans);
74     Formylove;
75 }
View Code

 

posted @ 2018-10-21 21:25  啊宸  阅读(165)  评论(0编辑  收藏  举报