2018 Multi-University Training Contest 2

Posted changer-qyz

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了2018 Multi-University Training Contest 2相关的知识,希望对你有一定的参考价值。

比个辣鸡.jpg

D.Game

题目传送门:http://acm.hdu.edu.cn/showproblem.php?pid=6312

 

题意:给一个数字n,就代表有一个1~n的序列,A和B两个人分别可以对这个序列进行操作,每次操作可以删去一个数及这个数所有的因子,轮到谁时谁无法再进行操作谁就输了,也就是刚好删除最后一个数的人赢。A先走,问A能不能赢。

分析:从1-n,我们可以先不看1,因为删除任何一个数都可以顺便把1删除了,那么只从2~n中选择就一定有一个胜者,如果这个状态A胜的话,我们就可以选择那个让我们胜的数,如果A输,我们可以先去掉1来转变状态,这样A还是会胜。所以A是必胜的,只用输出YES就行了。

技术分享图片
1 #include<bits/stdc++.h>
2 using namespace std;
3 int main(){
4     int n;
5     while(~scanf("%d",&n)){
6         printf("Yes
");
7     }
8     return 0;
9 } 
hdoj6312

 

G.Naive Operations

题目传送门:http://acm.hdu.edu.cn/showproblem.php?pid=6315

题意:有两个数字序列An和Bn,An里的元素一开始全为0,Bn数组由题目给出。现在有两种操作:

add l r 表示在An数组区间( l , r )中的每一个数都加1;query l r 表示查询区间( l , r )的ai/bi的和。

分析:涉及到区间更新区间和区间求和,所以考虑线段树。

当然如果单纯的用线段树一点一点更新肯定复杂度太高,只有当 ai 加1的次数能够整除 bi 时才会对区间答案有贡献,这样用线段树记录一开始每个点初始化为bi,每次访问的区间有这个点就减1,当为0时表示可以整除bi此位置的贡献加1,然后向下查找初始的bi的值重新赋值,而当查询区间的和时,加上每个点的贡献就行了。

技术分享图片
 1 #include<iostream>
 2 #include<cstring>
 3 #include<algorithm>
 4 #define maxn 100005
 5 using namespace std;
 6 struct point{
 7     int l,r;
 8     int num,sum,b;
 9     int lazy;
10 }tree[maxn<<2];
11 int n,m;
12 void build(int root,int l,int r){
13     tree[root].l=l;tree[root].r=r;
14     tree[root].sum=0;tree[root].lazy=0;
15     if (l==r){
16         cin >> tree[root].b;
17         tree[root].num=tree[root].b;
18         tree[root].sum=0;
19         return ;
20     } 
21     int mid=(l+r)/2;
22     build(root<<1,l,mid);
23     build(root<<1|1,mid+1,r);
24     tree[root].num=min(tree[root<<1].num,tree[root<<1|1].num);
25 }
26 void pushdown(int root){
27     if (tree[root].lazy){
28         tree[root<<1].lazy+=tree[root].lazy;
29         tree[root<<1|1].lazy+=tree[root].lazy;
30         tree[root<<1].num+=tree[root].lazy;
31         tree[root<<1|1].num+=tree[root].lazy;
32         tree[root].lazy=0;
33     }
34 }
35 void update(int root,int l,int r){
36     if (tree[root].l==l && tree[root].r==r){
37         tree[root].num--;
38         if (tree[root].num){
39             tree[root].lazy--;
40             return ;
41         }
42         else{
43             if (tree[root].l==tree[root].r){
44                 tree[root].sum++;
45                 tree[root].num=tree[root].b;
46                 return ;
47             }
48         }
49     }
50     pushdown(root);
51     int mid=(tree[root].l+tree[root].r)/2;
52     if (r<=mid) update(root<<1,l,r);
53     else if (l>mid) update(root<<1|1,l,r);
54     else{
55         update(root<<1,l,mid);
56         update(root<<1|1,mid+1,r);
57     }
58     tree[root].num=min(tree[root<<1].num,tree[root<<1|1].num);
59     tree[root].sum=tree[root<<1].sum+tree[root<<1|1].sum;
60 }
61 int query(int root,int l,int r){
62     if (tree[root].l==l && tree[root].r==r){
63         return tree[root].sum;
64     }
65     int mid=(tree[root].l+tree[root].r)/2;
66     if (r<=mid) return query(root<<1,l,r);
67     else if (l>mid) return query(root<<1|1,l,r);
68     else{
69         return query(root<<1,l,mid)+query(root<<1|1,mid+1,r);
70     }
71 }
72 int main(){
73     string ss;
74     int x,y;
75     ios::sync_with_stdio(false);
76     cin.tie(0);cout.tie(0);
77     while (cin >> n >> m){
78         build(1,1,n);
79         for (int i=0;i<m;i++){
80             cin >> ss >> x >> y;
81             if (ss[0]==a){
82                 update(1,x,y);
83             }
84             else{
85                 int ans=query(1,x,y);
86                 cout << ans << endl;
87             }
88         }
89     }    
90     return 0;
91 }
hdoj6315

 

J.Swaps and Inversions

题目传送门:http://acm.hdu.edu.cn/showproblem.php?pid=6318

题意:给一串数字序列,每一对逆序对需要耗费x。也可以任意相邻位置交换来减少逆序对数,交换一次的代价是y。问至少要付出的代价是多少。

分析:逆序对数==最少交换相邻位置次数,只需要求出逆序对数*min(x,y)。

技术分享图片
 1 #include<iostream>
 2 #include<algorithm> 
 3 #include<cstdio>
 4 #include<cstring>
 5 #define maxn 100005
 6 using namespace std;
 7 typedef long long ll;
 8 struct point{
 9     ll num;
10     int id;
11 }a[maxn];
12 ll tree[maxn];
13 int b[maxn];
14 int n,x,y;
15 ll ans;
16 int comp(point p,point q){
17     return p.num<q.num || p.num==q.num && p.id<q.id;  //数字相同是,注意离散化时的重复 
18 }
19 int lowbit(int x){
20     return x & (-x);
21 }
22 void add(int x,int num){
23     while (x<=n){
24         tree[x]+=num;
25         x+=lowbit(x);
26     }
27 }
28 ll query(int x){
29     ll sum=0;
30     while (x>0){
31         sum+=tree[x];
32         x-=lowbit(x);
33     }
34     return sum;
35 }
36 int main(){
37     ios::sync_with_stdio(false);
38     cin.tie(0);cout.tie(0);
39     while (cin >> n >> x >> y){
40         memset(tree,0,sizeof(tree));
41         for (int i=1;i<=n;i++){
42             cin >> a[i].num;
43             a[i].id=i;
44         }
45         sort(a+1,a+1+n,comp);
46         for (int i=1;i<=n;i++){
47             b[a[i].id]=i;
48         }
49         ans=0;
50         for (int i=1;i<=n;i++){
51             ans+=i-1-query(b[i]);
52             add(b[i],1);
53         }
54         if (x<=y) cout << x*ans << endl;
55         else cout << y*ans << endl;
56     }
57     return 0;
58 }
hdoj6318(树状数组+离散化)
技术分享图片
 1 #include<iostream>
 2 #include<cstring>
 3 #define maxn 100005
 4 using namespace std;
 5 typedef long long ll;
 6 ll ans;
 7 ll a[maxn],t[maxn];
 8 int n,x,y;
 9 void merge_sort(int l,int r){
10     if (r-l>=1){
11         int mid=(r-l)/2+l;
12         int p=l,q=mid+1,i=l;
13         merge_sort(l,mid);
14         merge_sort(mid+1,r);
15         while (p<=mid || q<=r){
16             if (q>r || p<=mid && a[p]<=a[q]) t[i++]=a[p++];
17             else {
18                 t[i++]=a[q++];
19                 ans+=mid+1-p;
20             }
21         }
22         for (i=l;i<=r;i++) a[i]=t[i];
23     }
24 }
25 int main(){
26     ios::sync_with_stdio(false);
27     cin.tie(0);cout.tie(0);
28     while (cin >> n >> x >> y){
29         for (int i=1;i<=n;i++){
30             cin >> a[i];
31         }
32         ans=0;
33         merge_sort(1,n);
34         if (x<=y) cout << x*ans << endl;
35         else cout << y*ans << endl;
36     }
37     return 0;
38 } 
hdoj6318(归并排序)

 

以上是关于2018 Multi-University Training Contest 2的主要内容,如果未能解决你的问题,请参考以下文章

2018 Multi-University Training Contest 2

2018 Multi-University Training Contest 9

2018 Multi-University Training Contest 4

2018 Multi-University Training Contest 4

2018 Multi-University Training Contest 3

2018 Multi-University Training Contest 8