2020牛客NOIP赛前集训营-提高组(第二场)总结&题解

it2023-12-14  60

文章目录

R e s u l t Result Result H y p e r l i n k Hyperlink Hyperlink D e s c r i p t i o n Description DescriptionT1 GCDT2 包含T3 前缀T4 移动 S u m m a r y Summary Summary S o l u t i o n s Solutions SolutionsT1T2T3T4 C o d e s Codes CodesT1T2T3T4 20 p t s 20pts 20pts 85 p t s 85pts 85pts

R e s u l t Result Result


H y p e r l i n k Hyperlink Hyperlink

https://ac.nowcoder.com/acm/contest/7607


D e s c r i p t i o n Description Description

T1 GCD

f ( x ) f(x) f(x)表示 x x x除了1以外的所有因数的 g c d gcd gcd,求 ∑ i = a b f ( x ) \sum _{i=a}^b f(x) i=abf(x) 数据范围: 1 < a < b ≤ 1 0 7 1<a<b\leq 10^7 1<a<b107


T2 包含

定义元素 b b b包含于二进制集合 A A A当且仅当 ∃ a ∈ A , a & b = b \exist a\in A,a\&b=b aA,a&b=b,现给定大小为 n n n的集合 A A A,有 m m m组询问,每次询问一个元素 b b b是否包含于 A A A集合 数据范围: n , m ≤ 1 0 5 , x , a i ≤ 1 0 6 n,m\leq 10^5,x,a_i\leq 10^6 n,m105,x,ai106


T3 前缀

n n n组询问,每次给出一个 t t t,再给定一个无限长的字符串,它的循环节是 s s s,试求这个串的一个最短前缀 s ‘ s^` s,使得 t t t s ‘ s^` s的一个子序列。其中 t t t的某些位置可能是 KaTeX parse error: Undefined control sequence: \* at position 1: \̲*̲,表示这个位置可以是任意字符。 数据范围: ∣ s ∣ ≤ 1 0 4 , t 的真正长度 ≤ 1 0 1 0 5 |s|\leq 10^4,t\text{的真正长度}\leq 10^{10^5} s104,t的真正长度10105


T4 移动

n n n扇门,你要从第0扇门出发,到达第 n + 1 n+1 n+1个位置,位移出一个位置需要1s 有 m m m个限制,每个限制 ( a , b , c ) (a,b,c) (a,b,c)告诉你,第 a a a扇门将在 [ b , c ] [b,c] [b,c]时段中关闭 问到达 n + 1 n+1 n+1的最小时间

数据范围: n , m ≤ 1 0 5 n,m\leq 10^5 n,m105


S u m m a r y Summary Summary

T1看到题目应该是要 O ( n ) O(n) O(n)的复杂度做出来的,然后考虑到 g c d gcd gcd与线性筛有关,就改一改线性筛就切了 T2的话做过上周刚做过一个类似的题,这题也是一样开个桶解决即可 T3题目谜语人,pass了 T4感觉很可做,先写出了一个跟题解一样的 d p dp dp,设 f i , j f_{i,j} fi,j表示到离散化后的第 i i i个时刻,能否到达第 j j j个位置,然后状态写炸了就去写了贪心 贪心大样例都过不了,害 然后就刚T3,我自己认为我是能过30%的数据的,但不知为何有锅QwQ

最后就只有100+100+0+35=235了


S o l u t i o n s Solutions Solutions

T1

容易发现质数的 f ( x ) = x f(x)=x f(x)=x 只含有一个质因子的数的 f ( x ) f(x) f(x)等于它的最小质因子 其它数的 f ( x ) = 1 f(x)=1 f(x)=1【1除外】 容易发现这些都可以在线性筛中做出来,时间复杂度 O ( m a x { a , b } ) O(max\{a,b\}) O(max{a,b})


T2

t i t_i ti表示 i i i这个元素是否属于 A A A,倒序扫描数组,将 i i i去除每一位的结果重新放入桶中 然后直接扫描即可,时间复杂度 O ( n + m + a i log ⁡ a i ) O(n+m+a_i\log a_i) O(n+m+ailogai)


T3

大模拟题 记录 t o t tot tot表示各个字母每次出现的次数 记录每个字母第几次出现在哪里

注意%的时候要边乘边模,类似于高精度 不然会炸

时间复杂度: O ( 26 ∣ s ∣ + n ∣ t ∣ ) O(26|s|+n|t|) O(26s+nt)


T4

85 p t s 85pts 85pts的贪心 将每个点的限制压入一个 v e c t o r vector vector,设 t t t表示到达 i + 1 i+1 i+1的最短时间,扫描限制转移即可 时间复杂度: O ( n + m ) O(n+m) O(n+m) 100 p t s 100pts 100pts d p dp dp


C o d e s Codes Codes

T1
#pragma GCC optimize(2) %:pragma GCC optimize(3) %:pragma GCC optimize("Ofast") %:pragma GCC optimize("inline") #include<cctype> #include<cstdio> #include<cstring> #include<algorithm> #define LL long long #define MAXN 10000010 using namespace std;LL a,b,s[MAXN]; int prime[MAXN],m,vis[MAXN],tot; inline LL read() { char c;LL d=1,f=0; while(c=getchar(),!isdigit(c)) if(c=='-') d=-1;f=(f<<3)+(f<<1)+c-48; while(c=getchar(),isdigit(c)) f=(f<<3)+(f<<1)+c-48; return d*f; } inline void prework(LL N) { for(register int i=2;i<=N;i++) { if(vis[i]==0) { s[i]=vis[i]=i;prime[++m]=i; } for(register int j=1;j<=m&&prime[j]*i<=N;j++) { if(prime[j]>vis[i]) break; vis[i*prime[j]]=prime[j]; if(!s[i*prime[j]]) //没有计算 { if(s[i]==1||s[prime[j]]==1) {s[i*prime[j]]=1;continue;}//如果转移的质因子已经互质了,那么乘起来显然还是会互质 if(vis[i]==vis[prime[j]]) s[i*prime[j]]=vis[i];//如果是同一质因子,可以转移 else s[i*prime[j]]=1;//否则,说明它出现了别的质因子,则赋值为1 } } } for(register int i=1;i<=N;i++) s[i]+=s[i-1];//求前缀和 return; } signed main() { a=read();b=read(); prework(max(a,b)); printf("%lld",s[b]-s[a-1]); }
T2

最短代码QwQ

#include<cstdio> int n,m,a; bool t[1<<20]; int main() { scanf("%d%d",&n,&m); for(int i=1;i<=n;i++) scanf("%d",&a),t[a]=true; for(int i=(1<<20)-1;i;i--) if(t[i]) for(int j=0;j<20;j++) if((i>>j)&1) t[i^(1<<j)]=true; for(int i=1;i<=m;i++) scanf("%d",&a),puts(t[a]?"yes":"no"); }
T3
#include<cctype> #include<cstdio> #include<cstring> #include<algorithm> #define LL long long #define mod 998244353 using namespace std;char s[10010],st[100010],ybd; int len,n,appear[26+150][10010]; LL xh,need,tot[26+150],qz[10010][26+150],once,ans,last; inline LL read() { char c;LL d=1,f=0; while(c=getchar(),!isdigit(c)) if(c=='-') d=-1;f=(f<<3)+(f<<1)+c-48; while(c=getchar(),isdigit(c)) f=(f<<3)+(f<<1)+c-48; return d*f; } inline LL ksm(LL x,LL y) { LL res=1; for(;y;y>>=1,(x*=x)%=mod) if(y&1) (res*=x)%=mod; return res; } inline bool tp() { for(register int i=1;i<=strlen(st+1);i++) if(st[i]!='*'&&!isdigit(st[i])&&tot[st[i]]==0) return true; return false; } signed main() { scanf("%s",s+1);len=strlen(s+1);s[len+1]=s[1]; for(register int i=1;i<=len;i++) { tot[s[i]]++; memcpy(qz[i],qz[i-1],sizeof(qz[i-1])); appear[s[i]][++appear[s[i]][0]]=i; qz[i][s[i]]++; } n=read(); while(n--) { scanf("%s",st+1); if(tp()) {puts("-1");continue;} ans=0;last=1; for(register int i=1;i<=strlen(st+1);i++) { ybd=st[i]; once=st[i]=='*'?len:tot[st[i]]; xh=0;need=0; if(isdigit(st[i+1])) { while(isdigit(st[i+1])) { xh=((xh<<3)+(xh<<1))%mod; need=((need<<3)+(need<<1)+st[++i]-48)%mod; (xh+=need/once)%=mod;need%=once; } } else need=1; if(ybd=='*') need+=once-(len-last+1); else need+=once-(tot[ybd]-qz[last-1][ybd]); if(need>once) need-=once,xh++; if(xh==0) xh=mod; if(need==0) need+=once,xh--; if(ybd!='*') { ans+=appear[ybd][need]-last+1; last=appear[ybd][need]%len+1; } else { ans+=need-last+1; last=need%len+1; } (ans+=len*xh%mod)%=mod; } printf("%lld\n",ans); } }
T4
20 p t s 20pts 20pts
#include<cctype> #include<cstdio> #include<cstring> #include<algorithm> #define LL long long using namespace std;int n,m; LL now,ans; struct node{int id;LL L,R;}p[100010]; inline bool cmp(node x,node y){return x.id<y.id;} inline LL read() { char c;LL d=1,f=0; while(c=getchar(),!isdigit(c)) if(c=='-') d=-1;f=(f<<3)+(f<<1)+c-48; while(c=getchar(),isdigit(c)) f=(f<<3)+(f<<1)+c-48; return d*f; } signed main() { n=read();m=read(); for(register int i=1;i<=m;i++) p[i].id=read(),p[i].L=read(),p[i].R=read(); sort(p+1,p+1+m,cmp); for(register int i=1;i<=m;i++) { if(p[i].id>now) { ans+=p[i].id-1-now; now=p[i].id-1; } if(ans+1<p[i].L) { ans++; now=p[i].id; } else { if(ans>p[i].R) { ans++; now=p[i].id; } else { ans=p[i].R+1; now=p[i].id; } } } if(now<n+1) ans+=(n+1)-now; printf("%lld",ans); }
85 p t s 85pts 85pts
#include<cctype> #include<cstdio> #include<cstring> #include<vector> #include<algorithm> #define LL long long using namespace std;int n,m,a,b,c,ti,t; vector<int>L[200010],R[200010]; inline LL read() { char c;LL d=1,f=0; while(c=getchar(),!isdigit(c)) if(c=='-') d=-1;f=(f<<3)+(f<<1)+c-48; while(c=getchar(),isdigit(c)) f=(f<<3)+(f<<1)+c-48; return d*f; } signed main() { n=read();m=read(); for(register int i=1;i<=m;i++) a=read(),b=read(),c=read(),L[a].push_back(b),R[a].push_back(c); t=1; for(register int i=1;i<=n;i++) { ti=t; for(register int j=0;j<L[i].size();j++) if(t>=L[i][j]&&t<=R[i][j]) t=R[i][j]+1; if(t==ti) t++; } printf("%d",t+1); }
最新回复(0)