Wannafly挑战赛9
链接:https://www.nowcoder.com/acm/contest/71/A
来源:牛客网
找一找
时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 262144K,其他语言524288K
64bit IO Format: %lld
空间限制:C/C++ 262144K,其他语言524288K
64bit IO Format: %lld
题目描述
给定n个正整数,请找出其中有多少个数x满足:在这n个数中存在数y=kx,其中k为大于1的整数
输入描述:
第一行输入一个n
接下来一行输入n个正整数ai
输出描述:
输出符合条件个数
示例1
输入
5 1 2 3 4 5
输出
2
说明
5个数中1和2符合条件,1是后面每个数的因子,2是4的因子
备注:
1≤n,ai
≤1000000
这个就是利用埃筛的思想枚举就可以了,1需要的次数比较多,特判下吧还可以离散化,应该跑的更快
#include <bits/stdc++.h> using namespace std; const int N=1e6+5; int b[N],a[N],sum; int main() { ios::sync_with_stdio(false); int n; cin>>n; for(int i=0; i<n; i++) cin>>a[i],b[a[i]]=1; for(int i=0; i<n; i++) { if(a[i]==1) { sum++; continue; } for(int j=a[i]+a[i]; j<N; j+=a[i]) if(b[j]==1) { sum++; break; } } printf("%d\n",sum); return 0; }
来源:牛客网
列一列
时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 262144K,其他语言524288K
64bit IO Format: %lld
空间限制:C/C++ 262144K,其他语言524288K
64bit IO Format: %lld
题目描述
小W在计算一个数列{An},其中A1=1,A2=2,An+2=An+1+An。尽管他计算非常精准,但很快他就弄混了自己的草稿纸,他找出了一些他计算的结果,但他忘记了这些都是数列中的第几项。
输入描述:
每行包括数列中的一项Ak(k<=100000)。总行数T<=30。输出描述:
对于每一项Ak,输出一行包括一个正整数k表示输入中数是数列的第几项。示例1
输入
2 3 5 8 13
输出
2 3 4 5 6
循环节是这样并不一定我代码能过,等等我的逻辑好像有问题,应该要有冲突的?还是py直接写吧,不难
#include<bits/stdc++.h> using namespace std; const int MD=1e8+7,N=1e5+5; int ans[N]; unordered_map<int,int>M; int main() { ans[0]=ans[1]=1; for(int i=2; i<N; i++) ans[i]=(ans[i-1]+ans[i-2])%MD,M[ans[i]]=i; string s; while(cin>>s) { int ans=0; for(int i=0; s[i]; ++i) ans=ans*10+(s[i]-'0'),ans%=MD; printf("%d\n",M[ans]); } return 0; }
ans = [] M = {} ans.append(1) M[1] = 1 ans.append(2) M[2] = 2 for i in range(100000): ans.append(ans[-1] + ans[-2]) M[ans[-1]] = len(ans) while True: try: n = input() if n: print(M[int(n)]) except EOFError: break
来源:牛客网
造一造
时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 262144K,其他语言524288K
64bit IO Format: %lld
空间限制:C/C++ 262144K,其他语言524288K
64bit IO Format: %lld
题目描述
WYF正试图用一个栈来构造一棵树,现在他已经构造了n个元素作为树的节点,只要将这n个元素依次入栈出栈就可以形成一棵树了。当然,这个问题与树并没有关系,所以它叫做WYF的栈。每次你可以入栈一个新元素或者当栈非空时出栈一个元素,n个元素必须依次入栈,而WYF希望其中第m个元素入栈之后,栈中恰好有k个元素,现在他想知道一共有多少种入栈出栈顺序满足这个条件。
输入描述:
第一行一个正整数T,表示数据组数。(1<=T<=10000)
对于每组数据包含一行三个正整数n,m,k。
输出描述:
对于每组数据输出一个正整数表示答案。
由于答案可能过大,所以只需要输出对109+7取模后的答案
示例1
输入
2 3 3 3 3 3 2
输出
1 2
示例2
输入
5 10 3 2 10 2 2 10 7 5 10 6 2 10 7 6
输出
6864 11934 2200 3780 924
示例3
输入
2 5 4 4 5 2 1
输出
5 14
备注:
1<=n,m,k<=106
n次入栈m次出栈的合法排列次数则可参考卡特兰数公式。C(n+m,m)-C(n+m,m-1)
看了另一个聚聚是处理倒着的逆元,骚的inv[i]=inv[p%i]*(p-p/i)%p递推得到逆元invf[i]=invf[i+1]*(i+1)%p这个公式反递推得到1!~n!的逆元C(n,m)=A(n,m)/m!=n!/(m!*(n-m)!)所以C(n,m)=C(n,n-m)所以C(n+m,m)-C(n+m,m-1)=C(n+m,(n+m)-n))-C(n+m,(n+m)-(m-1))=C(n+m,n)-C(n+m,n+1)
链接:https://www.nowcoder.com/acm/contest/71/B
来源:牛客网
链接:https://www.nowcoder.com/acm/contest/71/E
来源:牛客网
有3维BIT的,竟然还有一个dij的写法,666
#include<bits/stdc++.h> using namespace std; const int MD=1e9+7,N=2e6+5; int f[N],v[N]; int C(int n,int m) { if(m<0||m>n) return 0; return 1LL*f[n]*v[m]%MD*v[n-m]%MD; } int F(int n,int m) { return (C(n+m,m)-C(n+m,m-1)+MD)%MD; } int main() { v[0]=v[1]=f[0]=f[1]=1; for(int i=2; i<N; i++) f[i]=1LL*f[i-1]*i%MD,v[i]=1LL*v[MD%i]*(MD-MD/i)%MD; for(int i=2; i<N; i++) v[i]=1LL*v[i-1]*v[i]%MD; int n,m,k,T; scanf("%d",&T); while (T--) { scanf("%d%d%d",&n,&m,&k); printf("%d\n",1LL*F(m-1,m-k)*F(n-m+k,n-m)%MD); } return 0; }
#include<bits/stdc++.h> using namespace std; const int MD=1e9+7,N=2e6+5; int INV(int x) { return x==1?x:1LL*(MD-MD/x)*INV(MD%x)%MD; } int f[N],v[N]; int C(int n,int m) { if(m<0||m>n) return 0; return 1LL*f[n]*v[m]%MD*v[n-m]%MD; } int F(int n,int m) { return (C(n+m,n)-C(n+m,n+1)+MD)%MD; } int main() { f[0]=1; for (int i=1; i<N; i++) f[i]=1LL*f[i-1]*i%MD; v[N-1]=INV(f[N-1]); for (int i=N-2; i>=0; i--) v[i]=v[i+1]*(i+1LL)%MD; int n,m,k,T; scanf("%d",&T); while (T--) { scanf("%d%d%d",&n,&m,&k); printf("%d\n",1LL*F(m-1,m-k)*F(n-m+k,n-m)%MD); } return 0; }
来源:牛客网
数一数
时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 262144K,其他语言524288K
64bit IO Format: %lld
空间限制:C/C++ 262144K,其他语言524288K
64bit IO Format: %lld
题目描述
设s,t为两个字符串,定义f(s,t) = t的子串中,与s相等的串的个数。如f("ac","acacac")=3, f("bab","babab")=2。现在给出n个字符串,第i个字符串为si。你需要对,求出,由于答案很大,你只需要输出对 998244353取模后的结果。
输入描述:
第一行一个整数n。i
接下来n行每行一个仅由英文字母构成的非空字符串,第i个字符串代表s
。
输出描述:
共n行,第i行输出
对 998244353取模的结果。
示例1
输入
1 BALDRSKYKirishimaRain
输出
1
备注:
1 ≤ n ≤ 106
,所有字符串的总长度不超过2*106
B可以KMP 看毛片啊
找到最长的串KMP得到pre的前缀处理,然后对每个字符串进行贡献求积
#include <bits/stdc++.h> using namespace std; const int N=1e6+5,MD=998244353; string s[N]; int f[N+N]; int main() { int n,mi=N+N,ff,ans=1; cin>>n; for(int i=0; i<n; i++) { cin>>s[i]; if(s[i].size()<mi)mi=s[i].size(),ff=i; } for(int j=1; j<s[ff].size(); j++) { int k=f[j]; while(k&&s[ff][j]!=s[ff][k]) k=f[k]; f[j+1]=s[ff][j]==s[ff][k]?k+1:0; } for(int j=0; j<n; j++) { int cnt=0; for(int k=0,l=0; k<s[j].size(); k++) { while (l&&s[ff][l]!=s[j][k]) l=f[l]; if (s[ff][l]==s[j][k]) l++; if (l==mi) cnt++; } ans=ans*1LL*cnt%MD; } for(int i=0; i<n; i++) cout<<(s[i].size()==mi?ans:0)<<"\n"; return 0; }
来源:牛客网
组一组
时间限制:C/C++ 3秒,其他语言6秒
空间限制:C/C++ 65536K,其他语言131072K
Special Judge, 64bit IO Format: %lld
空间限制:C/C++ 65536K,其他语言131072K
Special Judge, 64bit IO Format: %lld
题目描述
有一个长为 n 的数列 A,其中有 m 个限制条件,条件有两种:
1、对于区间 [l,r],其区间元素按位或和等于 x
2、对于区间 [l,r],其区间元素按位与和等于 x
求出一个数列 A,使得满足给定的 m 个条件,保证有解。
1、对于区间 [l,r],其区间元素按位或和等于 x
2、对于区间 [l,r],其区间元素按位与和等于 x
求出一个数列 A,使得满足给定的 m 个条件,保证有解。
输入描述:
输入第一行两个正整数 n,m,意义如上
接下来 m 行,每行四个整数 op,l,r,x,表示一组限制
op = 1 表示是限制 1,op = 2 表示是限制 2
输出描述:
输出仅一行,n 个整数 ai
表示数列 A。要求 0 <= ai
< 109
示例1
输入
4 3 1 1 2 9 2 3 4 2 1 2 3 11
输出
1 9 2 6
备注:
1<=n,m<=10^5, 1<=l<=r<=n, 0<=x<2^20
有3维BIT的,竟然还有一个dij的写法,666
#include<iostream> #include<cstdio> #include<queue> const int N=1e5+5; int n,m,a[N],d[N]; int op[N],L[N],R[N],x[N]; int cnt,head[N]; struct Edge { int to,nxt,len; }edge[N<<3]; void init() { for(int i=0;i<=n;i++) head[i]=-1;cnt=0; } void addEdge(int from,int to,int len) { edge[cnt].to=to;edge[cnt].len=len;edge[cnt].nxt=head[from];head[from]=cnt++; } struct Node { int p,len; Node(int p=0,int len=0):p(p),len(len){} bool operator < (const Node &b) const { return len>b.len; } }; std::priority_queue<Node> q; void dijkstra() { for(int i=1;i<=n;i++) d[i]=N; d[0]=0;q.push(Node(0,0)); while(!q.empty()) { Node c=q.top();q.pop(); if(d[c.p]<c.len) continue; for(int i=head[c.p];~i;i=edge[i].nxt) { int v=edge[i].to,w=c.len+edge[i].len; if(d[v]>w) d[v]=w,q.push(Node(v,d[v])); } } } void solve(int k) { init(); for(int i=1;i<=m;i++) { if(op[i]==1) { if(x[i]>>k&1) addEdge(R[i],L[i]-1,-1); else addEdge(L[i]-1,R[i],0),addEdge(R[i],L[i]-1,0); } else { if(x[i]>>k&1) addEdge(L[i]-1,R[i],R[i]-L[i]+1),addEdge(R[i],L[i]-1,L[i]-1-R[i]); else addEdge(L[i]-1,R[i],R[i]-L[i]); } } for(int i=1;i<=n;i++) addEdge(i,i-1,0),addEdge(i-1,i,1); dijkstra(); for(int i=1;i<=n;i++) a[i]|=(d[i]-d[i-1])<<k; } int main() { scanf("%d%d",&n,&m); for(int i=1;i<=m;i++) scanf("%d%d%d%d",op+i,L+i,R+i,x+i); for(int i=0;i<20;i++) solve(i); for(int i=1;i<=n;i++) printf("%d%c",a[i],i<n?' ':'\n'); return 0; }
本文来自博客园,作者:暴力都不会的蒟蒻,转载请注明原文链接:https://www.cnblogs.com/BobHuang/p/8407316.html