2021.7.28考试总结[NOIP模拟26]

罕见的又改完了。

T1 神炎皇


吸取昨天三个出规律的教训,开场打完T2 20pts直接大力打表1h。

但怎么说呢,我不懂欧拉函数。(其实exgcd都忘了 于是只看出最大平方因子,不得不线性筛,爆拿60

正解又是看不懂的东西,取a和b的gcd d,把a,b同除d得到A,B,很容易想到(但好像不太容易证)A+B与AB互质。

那么要保证(A+B)d|ABd2,就要使(A+B)|d。又因为(A+B)d<n,所以(A+B)<根号n。

直接枚举A与B的和k,可以知道符合互质的AB数对有φ(k)对,d有n/k2对,相乘后累加即可。

code:

 1 #include<bits/stdc++.h>
 2 #define debug exit(0)
 3 #define int long long
 4 using namespace std;
 5 const int NN=2e7+5;
 6 int n,N,pri[NN],phi[NN],cnt,ans;
 7 bool vis[NN];
 8 inline int read(){
 9     int x=0,f=1;
10     char ch=getchar();
11     while(ch<'0'||ch>'9'){
12         if(ch=='-') f=-1;
13         ch=getchar();
14     }
15     while(ch>='0'&&ch<='9'){
16         x=(x<<1)+(x<<3)+(ch^48);
17         ch=getchar();
18     }
19     return x*f;
20 }
21 void write(int x){
22     if(x<0) putchar('-'), x=-x;
23     if(x>9) write(x/10);
24     putchar(x%10+'0');
25 }
26 void getphi(){
27     phi[1]=1;
28     for(int i=2;i<=N;i++){
29         if(!vis[i]) pri[++cnt]=i, phi[i]=i-1;
30         for(int j=1;j<=cnt&&pri[j]*i<=N;j++){
31             int now=pri[j]*i;
32             vis[now]=1;
33             if(i%pri[j]) phi[now]=phi[i]*(pri[j]-1);
34             else{ phi[now]=phi[i]*pri[j]; break; }
35         }
36     }
37 }
38 signed main(){
39     n=read(); N=sqrt(n);
40     getphi();
41     for(int i=2;i<=N;i++) ans+=phi[i]*(n/(i*i));
42     write(ans); putchar('\n');
43     return 0;
44 }
T1

T2 降雷皇


树状数组求最长上升子序列,中间维护方案数,如果同一位置有同样长度的方案,就把它们方案数累加。

用线段树也可。还能用双指针,因为fi相等的i电阻单调递减。

code:

 1 #include<bits/stdc++.h>
 2 #define debug exit(0)
 3 using namespace std;
 4 const int NN=1e5+5,p=123456789;
 5 int n,type,maxr,r[NN],res;
 6 struct node{
 7     int len,sum;
 8 }s[NN];
 9 inline node max(node a,node b){ 
10     if(a.len==b.len)
11         return (node){a.len,(a.sum+b.sum)%p};
12     else return a.len>b.len?a:b;
13 }
14 inline int read(){
15     int x=0,f=1;
16     char ch=getchar();
17     while(ch<'0'||ch>'9'){
18         if(ch=='-') f=-1;
19         ch=getchar();
20     }
21     while(ch>='0'&&ch<='9'){
22         x=(x<<1)+(x<<3)+(ch^48);
23         ch=getchar();
24     }
25     return x*f;
26 }
27 void write(int x){
28     if(x<0) putchar('-'), x=-x;
29     if(x>9) write(x/10);
30     putchar(x%10+'0');
31 }
32 inline int lowbit(int x){ return x&(-x); }
33 inline void insert(int pos,node v){
34     while(pos<=maxr){
35         s[pos]=max(s[pos],v);
36         pos+=lowbit(pos);
37     }
38 }
39 inline node query(int pos){
40     node res=(node){0,0};
41     while(pos){
42         res=max(res,s[pos]);
43         pos-=lowbit(pos);
44     }
45     return res;
46 }
47 void work(){
48     for(int i=1;i<=n;i++){
49         node nows=query(r[i]-1);
50         nows.len++;
51         if(nows.len==1) nows.sum++;
52         insert(r[i],nows);
53     }
54     node ans=query(maxr);
55     write(ans.len); putchar('\n');
56     if(type) write(ans.sum), putchar('\n'); 
57 }
58 signed main(){
59     n=read(); type=read();
60     for(int i=1;i<=n;i++) r[i]=read(), maxr=max(maxr,r[i]);
61     work();
62     return 0;
63 }
T2

T3 幻魔皇


树上全是菲波那契,再次在T3大力分类讨论。

考虑点对的LCA,LCA为点对中白点时可以直接用菲波那契求,根节点单算。

LCA为黑点时考虑黑点的两个子树,黑点的白色儿子单算。

预处理黑点为LCA,考虑最大深度为i中距离为j的点对fi,j,一波计算出解。

code:

 1 #include<bits/stdc++.h>
 2 #define debug exit(0)
 3 #define int long long
 4 using namespace std;
 5 const int NN=5e3+5,p=123456789;
 6 int n,fib[NN],ans[NN<<1],f[NN][NN<<1];
 7 inline int read(){
 8     int x=0,f=1;
 9     char ch=getchar();
10     while(ch<'0'||ch>'9'){
11         if(ch=='-') f=-1;
12         ch=getchar();
13     }
14     while(ch>='0'&&ch<='9'){
15         x=(x<<1)+(x<<3)+(ch^48);
16         ch=getchar();
17     }
18     return x*f;
19 }
20 void write(int x){
21     if(x<0) putchar('-'), x=-x;
22     if(x>9) write(x/10);
23     putchar(x%10+'0');
24 }
25 signed main(){
26     n=read(); fib[1]=fib[2]=1;
27     for(int i=3;i<=n;i++) fib[i]=(fib[i-1]+fib[i-2])%p;
28     for(int i=2;i<=n;i++){
29         for(int j=1;j<=n*2;j++) (f[i][j]+=f[i-1][j])%=p;
30         for(int j=3;j<=n;j++) (f[max(i,j)][i+j]+=fib[i-1]*fib[j-2]%p)%=p;
31     }
32     for(int i=2;i<=n;i++){
33         for(int j=5;j<=2*(n-i);j++) (ans[j]+=fib[i-1]*f[n-i][j]%p)%=p;
34         for(int j=i+2;j<=n;j++) (ans[j-i+1]+=fib[i-1]*fib[j-i-1]%p)%=p;
35         for(int j=i+2;j<=n;j++) (ans[j-i]+=fib[j-i-1]*fib[i-2]%p)%=p;
36     }
37     for(int i=3;i<=n;i++) (ans[i-1]+=fib[i-2])%=p;
38     for(int i=1;i<=2*n;i++) 
39         write(ans[i]), putchar(' '); putchar('\n');
40     return 0;
41 }
T3

 

posted @ 2021-07-28 17:38  keen_z  阅读(25)  评论(0编辑  收藏  举报