赞
踩
C 质因数个数
题目描述:给定正整数 n,请问有多少个质数是 n 的约数。
输入格式:输入的第一行包含一个整数 n。
输出格式:输出一个整数,表示 n 的质数约数个数。
样例输入:396
样例输出:3
提示:396 有 2, 3, 11 三个质数约数。
对于 30% 的评测用例,1 ≤ n ≤ 10000。
对于 60% 的评测用例,1 ≤ n ≤ 10^9。
对于所有评测用例,1 ≤ n ≤ 10^16。
评测链接:https://www.dotcpp.com/oj/problem2692.html
# include <iostream> # include <cmath> using namespace std; //检查是不是质因数 bool check(long num){ for(long i = 2;i * i <= num;i++) { long index = num / i; if(i * index == num) return false; } return true; } int main() { long num; cin>>num; long res = 0; for(long i = 2; i * i <= num; i++) { if(num % i == 0) { if(check(i)) res++; while(num % i == 0) { num /= i; } } } if(num > 1) res++; cout<<res; return 0; }
D 选数异或
题目描述:给定一个长度为 n 的数列 A1, A2, · · · , An 和一个非负整数 x,给定 m 次查询, 每次询问能否从某个区间 [l,r] 中选择两个数使得他们的异或等于 x 。
输入格式:输入的第一行包含三个整数 n, m, x 。
第二行包含 n 个整数 A1, A2, · · · , An 。
接下来 m 行,每行包含两个整数 li ,ri 表示询问区间 [li ,ri ] 。
输出格式:对于每个询问, 如果该区间内存在两个数的异或为 x 则输出 yes, 否则输出 no。
样例输入:4 4 1
1 2 3 4
1 4
1 2
2 3
3 3
样例输出:yes
no
yes
no
提示:显然整个数列中只有 2, 3 的异或为 1。
对于 20% 的评测用例,1 ≤ n, m ≤ 100;
对于 40% 的评测用例,1 ≤ n, m ≤ 1000;
对于所有评测用例,1 ≤ n, m ≤ 100000 ,0 ≤ x < 2^20 ,1 ≤ li ≤ ri ≤ n , 0 ≤ Ai < 2^20。
评测链接: https://www.dotcpp.com/oj/problem2665.html
#include<iostream> #include<map> using namespace std; typedef long long ll; const int N=1e5+5; ll n,m,x; int dp[N]; //a^b=x a,b中早出现的数字位置 map<ll,int> mp; int max(int a,int b){ return a>b?a:b; } int main() { ios_base::sync_with_stdio(0); cin.tie(0); //加速(很关键!) cin>>n>>m>>x; for(int i=1;i<=n;i++){ ll data; cin>>data; dp[i]=max(dp[i-1],mp[data^x]); //mp存放另一个数的位置 mp[data]=i; } while(m--){ int l,r; cin>>l>>r; if(dp[r]>=l) cout<<"yes\n"; else cout<<"no\n"; } return 0; }
E GCD
题目描述:给定两个不同的正整数 a, b,求一个正整数 k 使得 gcd(a + k, b + k) 尽可能大,其中 gcd(a, b) 表示 a 和 b 的最大公约数,如果存在多个 k,请输出所有满足条件的 k 中最小的那个。
输入格式:输入一行包含两个正整数 a, b,用一个空格分隔。
输出格式:输出一行包含一个正整数 k。
样例输入:5 7
样例输出:1
提示:对于 20% 的评测用例,a < b ≤ 10^5 ;
对于 40% 的评测用例,a < b ≤ 10^9 ;
对于所有评测用例,1 ≤ a < b ≤ 10^18 。
评测链接:https://www.dotcpp.com/oj/problem2682.html
#include<iostream> using namespace std; typedef long long ll; int main() { ll a, b; cin>>a>>b; if(a < b) { ll c = a; a = b; b = c; } ll sub = a - b; for(ll times = 2;times < 10;times++) { ll k1 = times * sub - a; ll k2 = (times - 1) * sub - b; if(k1 == k2 && k1 > 0) { cout<<k1<<endl; break; } } return 0; }
G 全排列的价值
题目描述:对于一个排列 A = (a1, a2, · · · , an),定义价值 ci 为 a1 至 ai−1 中小于 ai 的数的个数,即 bi = |{aj | j < i, aj < ai}|。定义 A 的价值为
。
给定 n,求 1 至 n 的全排列中所有排列的价值之和。
输入格式:输入一行包含一个整数 n 。
输出格式:输出一行包含一个整数表示答案,由于所有排列的价值之和可能很大,请输出这个数除以 998244353 的余数。
样例输入:3
样例输出:9
提示:1 至 3 构成的所有排列的价值如下:
(1, 2, 3) : 0 + 1 + 2 = 3 ;
(1, 3, 2) : 0 + 1 + 1 = 2 ;
(2, 1, 3) : 0 + 0 + 2 = 2 ;
(2, 3, 1) : 0 + 1 + 0 = 1 ;
(3, 1, 2) : 0 + 0 + 1 = 1 ;
(3, 2, 1) : 0 + 0 + 0 = 0 ;
故总和为 3 + 2 + 2 + 1 + 1 = 9。
对于 40% 的评测用例,n ≤ 20 ;
对于 70% 的评测用例,n ≤ 5000 ;
对于所有评测用例,2 ≤ n ≤ 10^6 。
评测链接:https://www.dotcpp.com/oj/problem2687.html
#include<iostream> using namespace std; typedef long long ll; const ll mod = 998244353; int main() { ll n, count = 1, val = 0, sum = 0; cin>>n; for(ll i = 2;i <= n;i++) { sum = (sum + i - 1) % mod; val = ((val * i) % mod + (count * sum) % mod) % mod; count *= i; count = count % mod; } cout<<val<<endl; return 0; }
J 重复的数
题目描述:给定一个数列 A = (a1, a2, · · · , an),给出若干询问,每次询问某个区间 [li ,ri ] 内恰好出现 ki 次的数有多少个。
输入格式:输入第一行包含一个整数 n 表示数列长度。
第二行包含 n 个整数 a1, a2, · · · , an,表示数列中的数。
第三行包含一个整数 m 表示询问次数。
接下来 m 行描述询问,其中第 i 行包含三个整数 li ,ri , ki 表示询问 [li ,ri ] 区间内有多少数出现了 ki 次。
输出格式:输出 m 行,分别对应每个询问的答案。
样例输入:3
1 2 2
5
1 1 1
1 1 2
1 2 1
1 2 2
1 3 2
样例输出:1
0
2
0
1
提示:对于 20% 的评测用例,n, m ≤ 500, 1 ≤ a1, a2, · · · , an ≤ 1000;
对于 40% 的评测用例,n, m ≤ 5000;
对于所有评测用例,1 ≤ n, m ≤ 100000, 1 ≤ a1, a2, · · · , an ≤ 100000, 1 ≤ li ≤ ri ≤ n, 1 ≤ ki ≤ n。
评测链接:https://www.dotcpp.com/oj/problem2691.html(一个很诡异的现象,输入用iostream会报超时,用cstdio就不会)
#include<cstdio> #include<algorithm> #include<cstring> const int N = 100005; using namespace std; struct query { int id; int l, r, k; }q[N]; bool cmp(query &a, query &b) { return a.l==b.l?a.r<b.r:a.l>b.l; } int cnt[N]; int nums[N]; int b[2*N]; int calc[N]; void del(int x) { calc[cnt[x]]--; cnt[x]--; calc[cnt[x]]++; } void add(int x) { calc[cnt[x]]--; cnt[x]++; calc[cnt[x]]++; } int main() { int n, l, r; scanf("%d",&n); for(int i=1;i<=n;i++) scanf("%d",&nums[i]); int m; scanf("%d",&m); for(int i=1;i<=m;i++) { q[i].id=i; scanf("%d%d%d",&q[i].l,&q[i].r,&q[i].k); } sort(q+1, q+m+1, cmp); l = 1,r = 0; for(int i=1;i<=m;i++) { while(l<q[i].l) del(nums[l++]);//移动端点 while(l>q[i].l) add(nums[--l]); while(r<q[i].r) add(nums[++r]); while(r>q[i].r) del(nums[r--]); b[q[i].id]=calc[q[i].k]; } for(int i=1;i<=m;i++) printf("%d\n",b[i]); return 0; }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。