2018年湘潭邀请赛
题目链接:
http://acm.hdu.edu.cn/listproblem.php?vol=53
A题:
题意:
总共有sum(a[i])篇文章,文章含有i条引用的文章数是ai,求最大的h使得最少有h篇文章含有至少h条引用。
思路:
二分,不过一开始把i和ai的含义读反wa了几发。
代码实现如下:
1 #include <set> 2 #include <map> 3 #include <deque> 4 #include <queue> 5 #include <stack> 6 #include <cmath> 7 #include <ctime> 8 #include <bitset> 9 #include <cstdio> 10 #include <string> 11 #include <vector> 12 #include <cstdlib> 13 #include <cstring> 14 #include <iostream> 15 #include <algorithm> 16 using namespace std; 17 18 typedef long long LL; 19 typedef pair<LL, LL> pLL; 20 typedef pair<LL, int> pLi; 21 typedef pair<int, LL> pil;; 22 typedef pair<int, int> pii; 23 typedef unsigned long long uLL; 24 25 #define lson rt<<1 26 #define rson rt<<1|1 27 #define lowbit(x) x&(-x) 28 #define name2str(name) (#name) 29 #define bug printf("*********\n") 30 #define debug(x) cout<<#x"=["<<x<<"]" <<endl 31 #define FIN freopen("D://code//in.txt","r",stdin) 32 #define IO ios::sync_with_stdio(false),cin.tie(0) 33 34 const double eps = 1e-8; 35 const int mod = 1000000007; 36 const int maxn = 2e5 + 7; 37 const double pi = acos(-1); 38 const int inf = 0x3f3f3f3f; 39 const LL INF = 0x3f3f3f3f3f3f3f3fLL; 40 41 int n; 42 int a[maxn]; 43 44 bool check(LL x) { 45 LL sum = 0; 46 for(int i = 0; i <= n; i++) { 47 if(i >= x) sum += a[i]; 48 } 49 return sum >= x; 50 } 51 52 int main(){ 53 while(~scanf("%d", &n)) { 54 for(int i = 0; i <= n; i++) { 55 scanf("%d", &a[i]); 56 } 57 LL ub = INF, lb = 0, mid, ans = 0; 58 while(ub >= lb) { 59 mid = (ub + lb) >> 1; 60 if(check(mid)) { 61 lb = mid + 1; 62 ans = mid; 63 } else { 64 ub = mid - 1; 65 } 66 } 67 printf("%lld\n", ans); 68 } 69 return 0; 70 }
B题:
题意:
你一共有n个小时,如果你花x个小时写一篇文章,那么这篇文章将会有x*a条引用,问你求h-index。
思路:
看样例大概可以知道每篇文章最多可以引用一次,我们容易发现我们只有每篇文章都只用1小时是最优的,则此时所写出的n篇文章所含有的引用条数分别为a,a+1,a+2……a+n-1。
我们假设答案是x,显然x>=a,则它在数组中的位置为x-a+1(下标从1开始),则数组中大于等于x的数共有n-x+a,由h-index的定义知,n-x+a>=x,咕x<=(n+a)/2,最大值就是(n+a)/2。
代码实现如下:
1 #include <set> 2 #include <map> 3 #include <deque> 4 #include <queue> 5 #include <stack> 6 #include <cmath> 7 #include <ctime> 8 #include <bitset> 9 #include <cstdio> 10 #include <string> 11 #include <vector> 12 #include <cstdlib> 13 #include <cstring> 14 #include <iostream> 15 #include <algorithm> 16 using namespace std; 17 18 typedef long long LL; 19 typedef pair<LL, LL> pLL; 20 typedef pair<LL, int> pLi; 21 typedef pair<int, LL> pil;; 22 typedef pair<int, int> pii; 23 typedef unsigned long long uLL; 24 25 #define lson rt<<1 26 #define rson rt<<1|1 27 #define lowbit(x) x&(-x) 28 #define name2str(name) (#name) 29 #define bug printf("*********\n") 30 #define debug(x) cout<<#x"=["<<x<<"]" <<endl 31 #define FIN freopen("D://code//in.txt","r",stdin) 32 #define IO ios::sync_with_stdio(false),cin.tie(0) 33 34 const double eps = 1e-8; 35 const int mod = 1000000007; 36 const int maxn = 2e5 + 7; 37 const double pi = acos(-1); 38 const int inf = 0x3f3f3f3f; 39 const LL INF = 0x3f3f3f3f3f3f3f3fLL; 40 41 int n, a; 42 43 int main(){ 44 while(~scanf("%d%d", &n, &a)) { 45 printf("%d\n", (n + a) / 2); 46 } 47 return 0; 48 }
C题:
题意:
求[Li,Ri]中的h-index。
思路:
对于每次查询,我们只需要二分答案x,然后看第x+1大的数是否大于等于x即可,主席树裸题。
代码实现如下:
1 #include <set> 2 #include <map> 3 #include <deque> 4 #include <queue> 5 #include <stack> 6 #include <cmath> 7 #include <ctime> 8 #include <bitset> 9 #include <cstdio> 10 #include <string> 11 #include <vector> 12 #include <cstdlib> 13 #include <cstring> 14 #include <iostream> 15 #include <algorithm> 16 using namespace std; 17 18 typedef long long LL; 19 typedef pair<LL, LL> pLL; 20 typedef pair<LL, int> pLi; 21 typedef pair<int, LL> pil;; 22 typedef pair<int, int> pii; 23 typedef unsigned long long uLL; 24 25 #define lson rt<<1 26 #define rson rt<<1|1 27 #define lowbit(x) x&(-x) 28 #define name2str(name) (#name) 29 #define bug printf("*********\n") 30 #define debug(x) cout<<#x"=["<<x<<"]" <<endl 31 #define FIN freopen("D://code//in.txt","r",stdin) 32 #define IO ios::sync_with_stdio(false),cin.tie(0) 33 34 const double eps = 1e-8; 35 const int mod = 1000000007; 36 const int maxn = 1e5 + 7; 37 const double pi = acos(-1); 38 const int inf = 0x3f3f3f3f; 39 const LL INF = 0x3f3f3f3f3f3f3f3fLL; 40 41 int n, q, cnt, x, y; 42 int a[maxn], root[maxn]; 43 44 struct node { 45 int l, r, sum; 46 }tree[maxn*40]; 47 48 void update(int l, int r, int& x, int y, int pos) { 49 tree[++cnt] = tree[y], tree[cnt].sum++, x = cnt; 50 if(l == r) return; 51 int mid = (l + r) >> 1; 52 if(mid >= pos) update(l, mid, tree[x].l, tree[y].l, pos); 53 else update(mid + 1, r, tree[x].r, tree[y].r, pos); 54 } 55 56 int query(int l, int r, int x, int y, int k) { 57 if(l == r) return l; 58 int mid = (l + r) >> 1; 59 int sum = tree[tree[y].l].sum - tree[tree[x].l].sum; 60 if(sum >= k) return query(l, mid, tree[x].l, tree[y].l, k); 61 else return query(mid + 1, r, tree[x].r, tree[y].r, k - sum); 62 } 63 64 int main() { 65 while(~scanf("%d%d", &n, &q)) { 66 cnt = 0; 67 for(int i = 1; i <= n; i++) scanf("%d", &a[i]), update(1, n, root[i], root[i-1], a[i]); 68 while(q--) { 69 scanf("%d%d", &x, &y); 70 int len = y - x + 1; 71 int ub = len, lb = 1, mid, ans = 1; 72 while(ub >= lb) { 73 mid = (ub + lb) >> 1; 74 int pp = query(1, n, root[x-1], root[y], len - mid + 1); 75 if(pp >= mid) { 76 lb = mid + 1; 77 ans = max(ans, mid); 78 } else { 79 ub = mid - 1; 80 } 81 } 82 printf("%d\n", ans); 83 } 84 for(int i = 0; i <= cnt; i++) { 85 tree[i].sum = 0; 86 } 87 } 88 return 0; 89 }
F题:
题意:
给你n对三元组和排序原则,要你输出排序后的编号。
思路:
直接sort即可,不过需要注意精度,我们可以稍加化简排除精度问题,去年比赛的时候因为精度贡献了两发罚时,最后同队学长提醒一句就A了。
代码实现如下:
1 #include <set> 2 #include <map> 3 #include <deque> 4 #include <queue> 5 #include <stack> 6 #include <cmath> 7 #include <ctime> 8 #include <bitset> 9 #include <cstdio> 10 #include <string> 11 #include <vector> 12 #include <cstdlib> 13 #include <cstring> 14 #include <iostream> 15 #include <algorithm> 16 using namespace std; 17 18 typedef long long LL; 19 typedef pair<LL, LL> pLL; 20 typedef pair<LL, int> pLi; 21 typedef pair<int, LL> pil;; 22 typedef pair<int, int> pii; 23 typedef unsigned long long uLL; 24 25 #define lson rt<<1 26 #define rson rt<<1|1 27 #define lowbit(x) x&(-x) 28 #define name2str(name) (#name) 29 #define bug printf("*********\n") 30 #define debug(x) cout<<#x"=["<<x<<"]" <<endl 31 #define FIN freopen("D://code//in.txt","r",stdin) 32 #define IO ios::sync_with_stdio(false),cin.tie(0) 33 34 const double eps = 1e-8; 35 const int mod = 1000000007; 36 const int maxn = 1e3 + 7; 37 const double pi = acos(-1); 38 const int inf = 0x3f3f3f3f; 39 const LL INF = 0x3f3f3f3f3f3f3f3fLL; 40 41 int n; 42 43 struct node { 44 int id; 45 LL a, b, c; 46 bool operator < (const node& x) const { 47 return (a + b) * x.c == (x.a + x.b) * c ? id < x.id : (a + b) * x.c < (x.a + x.b) * c; 48 } 49 }num[maxn]; 50 51 int main(){ 52 while(~scanf("%d", &n)) { 53 for(int i = 1; i <= n; i++) { 54 num[i].id = i; 55 scanf("%lld%lld%lld", &num[i].a, &num[i].b, &num[i].c); 56 } 57 sort(num + 1, num + n + 1); 58 for(int i = 1; i <= n; i++) { 59 printf("%d%c", num[i].id, i == n ? '\n' : ' '); 60 } 61 } 62 return 0; 63 }
G题:
题意:
给你两个字符串,然后其中aa、bb和abab可以消除或者在任意地方添加,然后问你s可以经过任意次操作变成t不?
思路:
这题的样例给的十分贴心,从第一个样例可以看出a和b可以互换位置,第二个样例可以推出a和b不能与c换位置,故对于s和t我们以c为分界,查看每一段内s的ab的奇偶是否等于t对应段的奇偶。
代码实现如下:
1 #include <set> 2 #include <map> 3 #include <deque> 4 #include <queue> 5 #include <stack> 6 #include <cmath> 7 #include <ctime> 8 #include <bitset> 9 #include <cstdio> 10 #include <string> 11 #include <vector> 12 #include <cstdlib> 13 #include <cstring> 14 #include <iostream> 15 #include <algorithm> 16 using namespace std; 17 18 typedef long long LL; 19 typedef pair<LL, LL> pLL; 20 typedef pair<LL, int> pLi; 21 typedef pair<int, LL> pil;; 22 typedef pair<int, int> pii; 23 typedef unsigned long long uLL; 24 25 #define lson rt<<1 26 #define rson rt<<1|1 27 #define lowbit(x) x&(-x) 28 #define name2str(name) (#name) 29 #define bug printf("*********\n") 30 #define debug(x) cout<<#x"=["<<x<<"]" <<endl 31 #define FIN freopen("D://code//in.txt","r",stdin) 32 #define IO ios::sync_with_stdio(false),cin.tie(0) 33 34 const double eps = 1e-8; 35 const int mod = 1000000007; 36 const int maxn = 1e4 + 7; 37 const double pi = acos(-1); 38 const int inf = 0x3f3f3f3f; 39 const LL INF = 0x3f3f3f3f3f3f3f3fLL; 40 41 string ans1, ans2; 42 char s[maxn], t[maxn]; 43 44 int main(){ 45 while(~scanf("%s%s", s, t)) { 46 int n = strlen(s), m = strlen(t); 47 ans1.clear(); ans2.clear(); 48 int num1 = 0, num2 = 0; 49 for(int i = 0; i < n; i++) { 50 if(s[i] == 'a') { 51 num1 = (num1 + 1) % 2; 52 } else if(s[i] == 'b') { 53 num2 = (num2 + 1) % 2; 54 } else { 55 if(num1) ans1 += 'a'; 56 if(num2) ans1 += 'b'; 57 ans1 += 'c'; 58 num1 = num2 = 0; 59 } 60 } 61 if(num1) ans1 += 'a'; 62 if(num2) ans1 += 'b'; 63 num1 = num2 = 0; 64 for(int i = 0; i < m; i++) { 65 if(t[i] == 'a') { 66 num1 = (num1 + 1) % 2; 67 } else if(t[i] == 'b') { 68 num2 = (num2 + 1) % 2; 69 } else { 70 if(num1) ans2 += 'a'; 71 if(num2) ans2 += 'b'; 72 ans2 += 'c'; 73 num1 = num2 = 0; 74 } 75 } 76 if(num1) ans2 += 'a'; 77 if(num2) ans2 += 'b'; 78 if(ans1 == ans2) puts("Yes"); 79 else puts("No"); 80 } 81 return 0; 82 }
K题:
题意:
在[a,b]内选择一个数x,同时在[c,d]中选择一个数y,使得x*y%2018=0的方案数。
思路:
枚举+容斥。
代码实现如下:
1 #include <set> 2 #include <map> 3 #include <deque> 4 #include <queue> 5 #include <stack> 6 #include <cmath> 7 #include <ctime> 8 #include <bitset> 9 #include <cstdio> 10 #include <string> 11 #include <vector> 12 #include <cstdlib> 13 #include <cstring> 14 #include <iostream> 15 #include <algorithm> 16 using namespace std; 17 18 typedef long long LL; 19 typedef pair<LL, LL> pLL; 20 typedef pair<LL, int> pLi; 21 typedef pair<int, LL> pil;; 22 typedef pair<int, int> pii; 23 typedef unsigned long long uLL; 24 25 #define lson rt<<1 26 #define rson rt<<1|1 27 #define lowbit(x) x&(-x) 28 #define name2str(name) (#name) 29 #define bug printf("*********\n") 30 #define debug(x) cout<<#x"=["<<x<<"]" <<endl 31 #define FIN freopen("D://code//in.txt","r",stdin) 32 #define IO ios::sync_with_stdio(false),cin.tie(0) 33 34 const double eps = 1e-8; 35 const int mod = 1000000007; 36 const int maxn = 2e5 + 7; 37 const double pi = acos(-1); 38 const int inf = 0x3f3f3f3f; 39 const LL INF = 0x3f3f3f3f3f3f3f3fLL; 40 41 int a, b, c, d; 42 43 int main(){ 44 while(~scanf("%d%d%d%d", &a, &b, &c, &d)) { 45 LL ans = 1LL * (b - a + 1) * (d / 2018 - (c - 1) / 2018); 46 ans += 1LL * (b / 2 - (a - 1) / 2 - (b / 2018 - (a - 1) / 2018)) * (d / 1009 - (c - 1) / 1009 - (d / 2018 - (c - 1) / 2018)); 47 ans += 1LL * (b / 1009 - (a - 1) / 1009 - (b / 2018 - (a - 1) / 2018)) * (d / 2 - (c - 1) / 2 - (d / 2018 - (c - 1) / 2018)); 48 ans += 1LL * (b / 2018 - (a - 1) / 2018) * (d - c + 1 - (d / 2018 - (c - 1) / 2018)); 49 printf("%lld\n", ans); 50 } 51 return 0; 52 }
去年和学长、同届一个OI大佬组队,全程被带飞,全程就贡献了一个F,希望今年湘潭邀请赛自己能够carry,夺一块好牌子吧~