NOIp2018集训test-10-15 (bike day1)

B 君的第一题

求斐波那契数列模n的循环节。

1、暴力bsgs,毕姥爷好像说循环节最大是6*n还是多少的,反之比较小,直接bsgs这题是可以过的。但是我非常蠢重载运算符的时候把相等返回成了小于,然后根本把结构体放不进map里去(我以为按道理只有等于的时候会炸,但事实上我根本放不进去啊)。然后改成不小于就可以过这题。

 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=1e7+9;
 7 typedef long long LL;
 8 typedef double db;
 9 using namespace std;
10 int T,p,sz=100000;
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 struct jz {
20     LL a[2][2];
21     friend bool operator <(const jz&A,const jz&B) {
22         For(i,0,1) For(j,0,1) if(A.a[i][j]!=B.a[i][j])
23             return A.a[i][j]<B.a[i][j];
24         return 0;
25     }
26     friend bool operator ==(const jz&A,const jz&B) {
27         return A.a[0][0]==B.a[0][0]&&A.a[0][1]==B.a[0][1]&&A.a[1][0]==B.a[1][0]&&A.a[1][1]==B.a[1][1];
28     }
29     friend jz operator *(const jz&A,const jz&B) {
30         jz rs;
31         For(i,0,1) For(j,0,1) {
32             rs.a[i][j]=0;
33             For(k,0,1) (rs.a[i][j]+=A.a[i][k]*B.a[k][j]%p)%=p;
34         }
35         return rs;
36     }
37 }tp,now,bs;
38 map<jz,int>mp;
39 
40 void solve() {
41     tp.a[0][0]=0,tp.a[0][1]=1,tp.a[1][0]=1,tp.a[1][1]=1;
42     bs.a[0][0]=1,bs.a[0][1]=0,bs.a[1][0]=0,bs.a[1][1]=1;
43     now=bs;
44     mp.clear();
45     For(i,1,sz) {
46         now=now*tp;
47         if(!mp[now]) mp[now]=i;
48         //cout<<mp[now]<<endl;
49         if(now==bs) {
50             printf("%d\n",i);
51             return;
52         }
53     }
54     jz x=now;
55     For(i,1,sz) {
56         if(mp[x]) {
57             LL ans=(LL)i*sz-mp[x];
58             if(ans!=0) {
59                 printf("%lld\n",ans);
60                 return;
61             }
62         }
63         x=x*now;
64     }
65 }
66 
67 #define ANS
68 int main() {
69 #ifdef ANS
70     freopen("shijiazhuang.in","r",stdin);
71     freopen("shijiazhuang.out","w",stdout);
72 #endif
73     read(T);
74     while(T--) {
75         read(p);
76         solve();
77     }
78     Formylove;
79 }
bsgs

2、我最讨厌的斐波那契的一坨性质

传送门

hdu题目传送门

  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=100007;
  7 typedef long long LL;
  8 typedef double db;
  9 using namespace std;
 10 int T;
 11 LL n,p;
 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 struct jz {
 21     LL a[2][2];
 22     friend jz operator *(const jz&A,const jz&B) {
 23         jz rs;
 24         For(i,0,1) For(j,0,1) {
 25             rs.a[i][j]=0;
 26             For(k,0,1) (rs.a[i][j]+=A.a[i][k]*B.a[k][j]%p)%=p;
 27         }
 28         return rs;
 29     }
 30 }bs,rs;
 31 
 32 void jzksm(LL b) {
 33     rs.a[0][0]=rs.a[1][1]=1;
 34     rs.a[1][0]=rs.a[0][1]=0;
 35     bs.a[0][0]=0; bs.a[0][1]=bs.a[1][0]=bs.a[1][1]=1;
 36     while(b) {
 37         if(b&1) rs=rs*bs;
 38         bs=bs*bs;
 39         b>>=1;
 40     }
 41 }
 42 
 43 LL ksm(LL a,LL b,LL p) {
 44     LL rs=1,bs=a%p;
 45     while(b) {
 46         if(b&1) rs=rs*bs%p;
 47         bs=bs*bs%p;
 48         b>>=1;
 49     }
 50     return rs;
 51 }
 52 
 53 LL gcd(LL a,LL b) { return !b?a:gcd(b,a%b); }
 54 
 55 LL lcm(LL a,LL b) {    return a/gcd(a,b)*b; } 
 56 
 57 LL solve() {
 58     if(p==2) return 3;
 59     if(p==3) return 8;
 60     if(p==5) return 20;
 61     LL a;
 62     if(ksm(5,(p-1)/2,p)==1) a=p-1;
 63     else a=(p+1)*2;
 64     LL ans=a;
 65     for(LL x=1;x*x<=a;x++) if(a%x==0) {
 66         LL tp=x;
 67         jzksm(tp);
 68         if(rs.a[0][0]==1&&rs.a[0][1]==0&&rs.a[1][0]==0&&rs.a[1][1]==1) ans=min(ans,tp); 
 69         tp=a/x;
 70         jzksm(tp);
 71         if(rs.a[0][0]==1&&rs.a[0][1]==0&&rs.a[1][0]==0&&rs.a[1][1]==1) ans=min(ans,tp);
 72     }
 73     return ans;
 74 }
 75 
 76 LL work(LL n) {
 77     if(n==1) return 1;
 78     LL tp=n,rs=1;
 79     for(LL x=2;x*x<=n;x++) if(tp%x==0) {
 80         LL m=0;
 81         while(tp%x==0) {
 82             tp/=x; m++;
 83         }
 84         p=x;
 85         rs=lcm(rs,solve()*ksm(p,m-1,1e18));
 86     }
 87     if(tp!=1) {
 88         p=tp;
 89         rs=lcm(rs,solve());
 90     }
 91     return rs;
 92 }
 93 
 94 #define ANS
 95 int main() {
 96 #ifdef ANS
 97     freopen("shijiazhuang.in","r",stdin);
 98     freopen("shijiazhuang.out","w",stdout);
 99 #endif
100     read(T);
101     For(cs,1,T) {
102         read(n);
103         printf("%lld\n",work(n));
104         //printf("Case #%d: %lld\n",cs,work(n));
105     }
106     Formylove;
107 }
View Code

 

B 君的第二题

1、我并没有想到的70分做法,开个堆把1~n的i/1放进去,每次取出最大i/x的然后把i/(x+1)放进堆即可。有人用这个A了这道题我也不知道他是怎么做到的。

2、100分做法,二分答案。二分被选上的最低分数,大于这个分数的都得被选,等于这个分数的可选可不选,判断一下是否合法就好了。

毕姥爷比较优秀用整数二分,我比较菜用实数二分但是过了我也没办法。

 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=1e5+7;
 7 typedef long long LL;
 8 typedef double db;
 9 using namespace std;
10 int n,m,ans[N],fl[N];
11 db p[N];
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 int ck(db pt) {
21     LL t1=0,t2=0;
22     For(i,1,n) {
23         int l=1,r=m,rs=0;
24         while(l<=r) {
25             int mid=((l+r)>>1);
26             if(p[i]>=pt*mid) rs=mid,l=mid+1;
27             else r=mid-1;
28         }
29         fl[i]=ans[i]=0;
30         if(rs) {
31             if(p[i]==pt*rs) { ans[i]=rs-1; fl[i]=1; t1+=rs-1; t2++; }
32             else { ans[i]=rs; t1+=rs; }
33         }
34     }
35     if(m>=t1&&m<=t1+t2) {
36         For(i,1,n) if(fl[i]&&t1<m) {
37             ans[i]++; t1++;
38         }
39         return 0;
40     }
41     if(m<t1) return -1;
42     if(m>t1+t2) return 1;
43 }
44 
45 #define ANS
46 int main() {
47 #ifdef ANS
48     freopen("taiyuan.in","r",stdin);
49     freopen("taiyuan.out","w",stdout);
50 #endif
51     read(n); read(m);
52     db l=0.0,r=0.0;
53     For(i,1,n) {
54         read(p[i]);
55         r=max(r,p[i]);
56     }
57     for(;;) {
58         db mid=(l+r)/2.0;
59         if(ck(mid)==0) break;
60         if(ck(mid)==-1) l=mid;
61         else r=mid;
62     }
63     For(i,1,n) printf("%d\n",ans[i]);
64     Formylove;
65 }
View Code

 

B 君的第三题

曼哈顿距离和切比雪夫距离的相互转换

题目转换为求一点到所有点的切比雪夫距离最小,再转换坐标变成求曼哈顿距离最小。于是x,y分开考虑,每一维取中位数就好了。

然后要求点数,就是中位数围成的矩形中的整点个数。因为现在的坐标转回去的时候是(x+y)/2,(x-y)/,2所以实际上是这个矩形中横轴坐标奇偶相同的整点个数。特判当矩形只剩下一个点,而这个点奇偶不同时,要抖动一下找四周的点作为实际答案。

 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=1e5+7;
 7 typedef long long LL;
 8 typedef double db;
 9 using namespace std;
10 int n,anstot;
11 LL xx[N],yy[N],ansnum=1e18;
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 void calc(LL x,LL y) {
21     LL rs=0;
22     For(i,1,n) 
23         rs+=abs(xx[i]-x)+abs(yy[i]-y);
24     if(rs<ansnum) ansnum=rs,anstot=1;
25     else if(rs==ansnum) anstot++;
26 }
27 
28 LL odd(LL l,LL r) {
29     if((l&1)&&(r&1)) return (r-l+2)/2;
30     else return (r-l+1)/2;
31 }
32 
33 LL even(LL l,LL r) {
34     if(!(l&1)&&!(r&1)) return (r-l+2)/2;
35     else return (r-l+1)/2;
36 }
37 
38 void solve(LL xl,LL xr,LL yl,LL yr) {
39     if(xl==xr&&yl==yr&&(xl+yl)%2!=0) {
40         calc(xl-1,yl);
41         calc(xl+1,yl);
42         calc(xl,yl-1);
43         calc(xl,yl+1);
44     }
45     else {
46         calc(xl,yl);
47         anstot=odd(xl,xr)*odd(yl,yr)+even(xl,xr)*even(yl,yr);
48     }
49 }
50 
51 #define ANS
52 int main() {
53 #ifdef ANS
54     freopen("zhengzhou.in","r",stdin);
55     freopen("zhengzhou.out","w",stdout);
56 #endif
57     read(n);
58     For(i,1,n) {
59         LL x,y;
60         read(x); read(y);
61         xx[i]=x+y;
62         yy[i]=x-y;
63     }
64     sort(xx+1,xx+n+1);
65     sort(yy+1,yy+n+1);
66     solve(xx[(n+1)/2],xx[(n+2)/2],yy[(n+1)/2],yy[(n+2)/2]);
67     printf("%lld\n%d\n",ansnum/2,anstot);
68     Formylove;
69 }
View Code

 

 

其实我特别后悔当年第一次见到毕姥爷之后没有立刻退役。

要是人生重来,不学OI了,也不学理了,我就想安安静静地当个文科生。说实话我对史地都挺感兴趣的,政治无感但好歹是我高一学得最好的每次月考帮我拉分的一个科目,而理化生,抱歉半毛钱兴趣都没有,如果不是竞赛应该会认真考虑读文吧。虽然读文好像不能学计算机了,那就不学了吧,大概多读书多到处走以后当个写东西的,这样的人生可能更适合我?

我邪在沙海说过里有一句话

对于弱者的帮助有时候只能让他变得更弱,在这个社会里,在自己不擅长的行业被淘汰,有时候是一种幸运,你可以去寻找真正适合自己的生活,而帮助弱者,把他们在自己不擅长的行业中抬到一个太高的位置,往往会让他们死无葬身之地。

这一次无论能走到哪里,都是最后一次了,我未来再不会碰算法竞赛相关了。忘了从哪听到的一句话大概是“所有的热爱最终都变成执念”,我现在在干的事情已经完全脱离我的初衷了,我和之前的我状态完全不一样了。而且我更是清晰且悲哀地认识到,竞赛可能真的并不适合我。当然,不适合和不做是两码事,于是现在OI对于我已经从目的变成仅仅手段了,这有违我的初心,是我所不喜欢的,也是让现在的我难受的,但是我没有别的办法。现在的我能做的只有尽我所能地去做我能做到的所有事情。

 

posted @ 2018-10-15 22:34  啊宸  阅读(195)  评论(0编辑  收藏  举报