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 }
View Code

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 }
View Code

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 }
View Code

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 }
View Code

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 }
View Code

 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 }
View Code

 

去年和学长、同届一个OI大佬组队,全程被带飞,全程就贡献了一个F,希望今年湘潭邀请赛自己能够carry,夺一块好牌子吧~

posted @ 2019-02-24 22:55  Dillonh  阅读(540)  评论(0编辑  收藏  举报