2018 ACM-ICPC 宁夏邀请赛

Posted mygirlfriends

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了2018 ACM-ICPC 宁夏邀请赛相关的知识,希望对你有一定的参考价值。

A 小甜甜

技术分享图片
 1 #include <iostream>
 2 #include <cstdio>
 3 #include <algorithm>
 4 #include <cmath>
 5 #include <vector>
 6 #include <queue>
 7 #include <set>
 8 #include <map>
 9 #include <string>
10 #include <string.h>
11 #include <stdlib.h>
12 #include <time.h>
13 #include <climits>
14 
15 using namespace std;
16 
17 const int maxN=5e6+7;
18 
19 unsigned int sta[maxN];
20 int to[maxN];
21 int top=0;
22 
23 int n,p,q,m;
24 unsigned int SA,SB,SC;
25 long long ans=0;
26 
27 unsigned int rng61(){
28     SA^=SA<<16;
29     SA^=SA>>5;
30     SA^=SA<<1;
31     unsigned int t=SA;
32     SA=SB;
33     SB=SC;
34     SC^=t^SA;
35     return SC;
36 }
37 
38 void PUSH(unsigned int x,int i){
39     //cerr<<"PUSH"<<x<<endl;
40     top++;
41     sta[top]=x;
42 
43     if (x>sta[to[top-1]]) to[top]=top;
44     else to[top]=to[top-1];
45 
46     ans=ans^(1LL*sta[to[top]]*i);
47 }
48 
49 void POP(int i){
50     //cerr<<"POP"<<endl;
51     if (top==0) return;
52     top--;
53     if (top==0) return;
54 
55     ans=ans^(1LL*sta[to[top]]*i);
56 }
57 
58 void gen(){
59     scanf("%d%d%d%d%u%u%u",&n,&p,&q,&m,&SA,&SB,&SC);
60     ans=top=0;
61 
62     for (int i=1;i<=n;i++) {
63         if (rng61()%(p+q)<p) PUSH(rng61()%m+1,i);
64         else POP(i);
65     }
66 
67     printf("%lld
",ans);
68 }
69 
70 
71 int main(){
72     int T;
73     scanf("%d",&T);
74     int kcase=0;
75     while (T--){
76         printf("Case #%d: ",++kcase);
77         gen();
78     }
79     return 0;
80 }
View Code

 

B 小洛洛

技术分享图片
 1 #include <cstdio>
 2 #include <cstring>
 3 #include <algorithm>
 4 #include <iostream>
 5 #include <cstdlib>
 6 #include <cmath>
 7 using namespace std;
 8 
 9 typedef long long ll;
10 
11 const int N = 55;
12 struct P_ {
13     int x, y;
14     P_ operator-(const P_ &r) const {
15         return (P_) { x - r.x, y - r.y };
16     }
17     double norm() const {
18         return hypot((double)x, (double)y);
19     }
20     double operator*(const P_ &r) const {
21         return (double)x * r.x + (double)y * r.y;
22     }
23 } pts[N];
24 
25 int main() {
26     int T;
27     scanf("%d", &T);
28     for(int it = 1; it <= T; ++it) {
29         int n;
30         scanf("%d", &n);
31         for(int i = 0; i < n; ++i) {
32             scanf("%d%d", &pts[i].x, &pts[i].y);
33         }
34         pts[n] = pts[0];
35         pts[n + 1] = pts[1];
36         P_ p0;
37         scanf("%d%d", &p0.x, &p0.y);
38         double ans = 0.0;
39         for(int i = 0; i < n; ++i) {
40             double r = (p0 - pts[i + 1]).norm();
41             P_ a = pts[i + 1] - pts[i],
42                b = pts[i + 2] - pts[i + 1];
43             double th = acos(a * b / (a.norm() * b.norm()));
44             ans += r * th;
45         }
46         printf("Case #%d: %.3f
", it, ans);
47     }
48     return 0;
49 }
View Code

 

C BPM136

计算出偏移量即可

技术分享图片
 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cmath>
 4 #include<cstring>
 5 #include<cstdlib>
 6 #include<algorithm>
 7 
 8 using namespace std;
 9 
10 typedef long long ll;
11 
12 const int N = 100;
13 
14 char s1[N];
15 char s2[N];
16 int n,m;
17 
18 char s[N];
19 
20 int main() {
21     int T,kcas=0;
22     scanf("%d",&T);
23     while(T--) {
24         scanf("%d%d",&n,&m);
25         scanf("%s%s%s",s1,s2,s);
26         int ca=s1[0]-s2[0];
27 
28         printf("Case #%d: ",++kcas);
29         for(int i=0;i<m;i++) putchar((s[i]-A+(ca)+26)%26+A);
30         puts("");
31     }
32     return 0;
33 }
View Code

 

D 小洛洛

技术分享图片
 1 #include <cstdio>
 2 #include <cstring>
 3 #include <algorithm>
 4 #include <iostream>
 5 #include <cstdlib>
 6 using namespace std;
 7 
 8 int main() {
 9     int T;
10     scanf("%d", &T);
11     for(int it = 1; it <= T; ++it) {
12         int n, m;
13         scanf("%d%d", &n, &m);
14         double ans1 = (n == 1 ? 1 : 0.5);
15         double ans2 = (m + 1.0) / (2.0 * m);
16         printf("Case #%d: %.6f %.6f
", it, ans1, ans2);
17     }
18     return 0;
19 }
View Code

 

E 小洛洛

模拟即可,一脸蛋疼

技术分享图片
 1 #include <cstdio>
 2 #include <cstring>
 3 #include <algorithm>
 4 #include <iostream>
 5 #include <cstdlib>
 6 using namespace std;
 7 
 8 const int N = 500003;
 9 struct T_ {
10     int n;
11     int v[3];
12     T_ *ch[4];
13 } ss[N], *sp;
14 
15 void dfs_(T_ *c) {
16     if(!c) return;
17     for(int i = 0; i < c->n; ++i) {
18         if(i != 0)
19             putchar( );
20         printf("%d", c->v[i]);
21     }
22     putchar(
);
23     for(int i = 0; i <= c->n; ++i)
24         dfs_(c->ch[i]);
25 }
26 
27 
28 void fuxk_rt_(T_ *&c) {
29     if(c->n == 3) {
30         T_ *c2 = sp++, *nc = sp++;
31         *c2 = (T_){ 1, { c->v[2] }, { c->ch[2], c->ch[3] } };
32         *nc = (T_){ 1, { c->v[1] }, { c, c2 } };
33         c->n = 1;
34         c = nc;
35     }
36 }
37 
38 bool insert_(T_ *&c, int val) {
39     if(!c) {
40         *(c = sp++) = (T_) { 1, { val }, { NULL, NULL } };
41         return true;
42     } else if(c->n == 3)
43         return false;
44     else if(c->ch[0]) {
45 rerun:
46         int i = 0;
47         while(i < c->n && c->v[i] < val) ++i;
48 
49         T_ *sub = c->ch[i];
50         if(!insert_(sub, val)) {
51             for(int j = c->n; j > i; --j) 
52                 c->v[j] = c->v[j - 1];
53             for(int j = ++c->n; j > i; --j) 
54                 c->ch[j] = c->ch[j - 1];
55 
56             T_ *c2 = sp++;
57             *c2 = (T_){ 1, { sub->v[2] }, { sub->ch[2], sub->ch[3] } };
58             sub->n = 1;
59             c->v[i] = sub->v[1];
60             c->ch[i] = c2;
61             swap(c->ch[i], c->ch[i + 1]);
62             goto rerun;
63         }
64         return true;
65     } else {
66         int i = 0;
67         while(i < c->n && c->v[i] < val) ++i;
68         for(int j = c->n; j > i; --j) 
69             c->v[j] = c->v[j - 1];
70         ++c->n;
71         c->ch[c->n] = NULL;
72         c->v[i] = val;
73         return true;
74     }
75 }
76 
77 int main() {
78     int T;
79     scanf("%d", &T);
80     for(int it = 1; it <= T; ++it) {
81         int n;
82         scanf("%d", &n);
83 
84         sp = ss;
85         T_ *rt = NULL;
86         for(int i = 0; i < n; ++i) {
87             int x;
88             scanf("%d", &x);
89             while(!insert_(rt, x))
90                 fuxk_rt_(rt);
91         }
92         printf("Case #%d:
", it);
93         dfs_(rt);
94     }
95     return 0;
96 }
View Code

 

F BPM136

考虑floyed,每次加进点更新就好了

技术分享图片
 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cmath>
 4 #include<cstring>
 5 #include<cstdlib>
 6 #include<algorithm>
 7 
 8 using namespace std;
 9 #define int long long
10 
11 const int N = 205;
12 const int M = 20005;
13 
14 int d[N][N];
15 int f[N][N];
16 int a[N];
17 int n,m;
18 
19 struct ques {
20     int x,y,id;
21     int w;
22     int ans;
23 }q[M];
24 
25 bool cmp_id(ques a,ques b) {
26     return a.id<b.id;
27 }
28 bool cmp_w(ques a,ques b) {
29     return a.w>b.w;
30 }
31 
32 struct node {
33     int x;
34     int w;
35 }p[N];
36 
37 bool cmp_node_w(node a,node b) {
38     return a.w<b.w;
39 }
40 
41 bool vis[N];
42 
43 main() {
44     int T,kcas=0;
45     scanf("%lld",&T);
46     while(T--) {
47         scanf("%lld%lld",&n,&m);
48         for(int i=1;i<=n;i++) {
49                scanf("%lld",&a[i]);
50             p[i].w=a[i];
51             p[i].x=i;
52         }
53         memset(vis,0,sizeof(vis));
54         for(int i=1;i<=n;i++) {
55             for(int j=1;j<=n;j++) {
56                 scanf("%lld",&d[i][j]);
57                 f[i][j]=d[i][j];
58             }
59         }
60 
61         for(int i=1;i<=m;i++) {
62             scanf("%lld%lld%lld",&q[i].x,&q[i].y,&q[i].w);
63             q[i].id=i;
64         }
65 
66         sort(q+1,q+m+1,cmp_w);
67         sort(p+1,p+n+1,cmp_node_w);
68 
69         int l=1;
70         for(int o=m;o>=1;o--) {
71             while(l <= n && p[l].w<=q[o].w) {
72                 int k=p[l].x;
73                 vis[k]=1;
74                 for(int i=1;i<=n;i++) {
75                     for(int j=1;j<=n;j++) {
76                         if(f[i][k]+f[k][j]<f[i][j]) {
77                             f[i][j]=f[i][k]+f[k][j];
78                         }
79                     }
80                 }
81                 l++;
82             }
83 
84             q[o].ans=f[q[o].x][q[o].y];
85         }
86         sort(q+1,q+m+1,cmp_id);
87         printf("Case #%lld:
",++kcas);
88         for(int i=1;i<=m;i++) {
89             printf("%lld
",q[i].ans);
90         }
91     }
92     return 0;
93 }
View Code

 

G BPM136

树形DP,fi,j表示在i的子树中选j个,在最优情况下的贡献是多少

转移min(size,m)之后复杂度为O(nk)

whx的证明:找个割出来,割以上子树大小大于k,割以下子树大小小于k。然后上面最多n/k个合并,下面每对在割上共一个点的点对被算一次,每人最多和k个被算

每条边的贡献为p(k-p)

技术分享图片
  1 /* ***********************************************
  2 Author        :BPM136
  3 Created Time  :2018/7/17 21:39:31
  4 File Name     :G.cpp
  5 ************************************************ */
  6 
  7 #include<iostream>
  8 #include<cstdio>
  9 #include<algorithm>
 10 #include<cstdlib>
 11 #include<cmath>
 12 #include<cstring>
 13 #include<vector>
 14 using namespace std;
 15 
 16 typedef long long ll;
 17 
 18 const int N = 100005;
 19 const int M = 105;
 20 const ll inf = 1e17;
 21 
 22 struct edge {
 23     int y,w,next;
 24 }e[N<<1];
 25 int last[N],ne;
 26 
 27 ll f[N][M];
 28 ll sum[N][M];
 29 int siz[N];
 30 int n,m;
 31 
 32 void add(int x,int y,int w) {
 33     e[++ne].y=y; e[ne].w=w; e[ne].next=last[x]; last[x]=ne;
 34 }
 35 void add2(int x,int y,int w) {
 36     add(x,y,w); 
 37     add(y,x,w);
 38 }
 39 
 40 ll cur[M];
 41 ll sum_cur[M];
 42 int du[N];
 43 void dfs(int x,int pre) {
 44     siz[x]=0;
 45     f[x][0]=0; for(int i=1;i<=m;i++) f[x][i]=inf;
 46     sum[x][0]=0; for(int i=1;i<=m;i++) sum[x][i]=inf;
 47     int flag=1;
 48     for(int i=last[x];i!=0;i=e[i].next) {
 49         int y=e[i].y;
 50         if(y==pre) continue;
 51         flag=0;
 52         dfs(y,x);
 53 
 54         for(int p=0;p<=m;p++) cur[p]=f[x][p],f[x][p]=inf;
 55         for(int p=0;p<=m;p++) sum_cur[p]=sum[x][p],sum[x][p]=inf;
 56         int bound0=min(m,siz[x]);
 57         int bound1=min(m,siz[y]);
 58         for(int p=0;p<=bound0;p++) {
 59             for(int q=0;q<=bound1 && p+q<=m;q++) {
 60                 if(f[x][p+q]>cur[p]+f[y][q]+(ll)e[i].w*(m-q)*q) {
 61                     f[x][p+q]=cur[p]+f[y][q]+(ll)e[i].w*(m-q)*q;
 62                 }
 63             }
 64         }
 65         siz[x]+=siz[y];
 66     }
 67     if(siz[x]==0 && flag==1) {
 68         siz[x]=1;
 69         f[x][1]=0;
 70         sum[x][1]=0;
 71     }
 72 }
 73 
 74 int main() {
 75     int T,kcas=0;
 76     scanf("%d",&T);
 77     while(T--) {
 78         scanf("%d%d",&n,&m);
 79         memset(last,0,sizeof(last));
 80         memset(du,0,sizeof(du));
 81         ne=0;
 82         int tmp;
 83         for(int i=1;i<n;i++) {
 84             int x,y,w;
 85             scanf("%d%d%d",&x,&y,&w);
 86             tmp=w;
 87             add2(x,y,w);
 88             du[x]++; du[y]++;
 89         }
 90         if(n==2) {
 91             if(m==1) printf("Case #%d: 0
",++kcas);
 92             if(m==2) printf("Case #%d: %d
",++kcas,tmp);
 93             continue;
 94         }
 95 
 96         int root=0;
 97         for(int i=1;i<=n;i++) if(du[i]!=1) {
 98             root=i;
 99             break;
100         }
101         dfs(root,-1);
102         printf("Case #%d: %lld
",++kcas,f[root][m]);
103     }
104     return 0;
105 }
View Code

 

H 小甜甜+BPM136

考虑如果需要zi次才能打到对手,那么微扰法,只需要ATKj * Zi < ATKi * Zj 就是好的,于是sort即可

技术分享图片
 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cmath>
 4 #include<cstring>
 5 #include<algorithm>
 6 #include<cstdlib>
 7 
 8 using namespace std;
 9 
10 typedef long long ll;
11 
12 const int N = 100005;
13 
14 struct node {
15     ll ATK;
16     ll HP;
17     ll Z;
18     ll S;
19 }a[N];
20 
21 bool cmp(node a,node b) {
22     return b.ATK*a.Z<b.Z*a.ATK;
23 }
24 
25 int n;
26 
27 ll EF(ll a) {
28     ll l=1,r=1e9;
29     ll ret=0;
30     while(l<=r) {
31         ll mid=(l+r)>>1;
32         if(mid*mid+mid-2*a>=0) {
33             ret=mid;
34             r=mid-1;
35         } else l=mid+1;
36     }
37     return ret;
38 }
39 
40 int main() {
41     int T,kcas=0;
42     scanf("%d",&T);
43     while(T--) {
44         scanf("%d",&n);
45         for(int i=1;i<=n;i++) {
46             scanf("%lld%lld",&a[i].HP,&a[i].ATK);
47             a[i].Z=EF(a[i].HP);
48         }
49         sort(a+1,a+n+1,cmp);
50         for(int i=1;i<=n;i++) a[i].S=a[i-1].S+a[i].Z;
51         ll ans=0;
52         for(int i=1;i<=n;i++) ans+=a[i].S*a[i].ATK;
53         printf("Case #%d: %lld
",++kcas,ans);
54     }
55     return 0;
56 }
View Code

 

I 待补

J 待补

K 小洛洛

状压暴力check,大力出奇迹

技术分享图片
 1 #include <cstdio>
 2 #include <cstring>
 3 #include <algorithm>
 4 #include <iostream>
 5 #include <cstdlib>
 6 #include <map>
 7 using namespace std;
 8 
 9 typedef long long ll;
10 
11 const int N = 40;
12 int n;
13 ll MOD, w[N], nei[N];
14 bool tbl[N][N];
15 
16 map<ll, int> mp;
17 
18 ll f_(ll rest) {
19     if(!rest) return 1;
20     if(mp.find(rest) == mp.end()) {
21         int i = 0;
22         while(~rest & (1LL << i)) ++i;
23         ll ret = 0;
24         ll cnei = nei[i] & rest;
25         if(~cnei & (1LL << i)) { // not sel
26             ll ws = 1;
27             for(int j = 0; j < n; ++j)
28                 if(cnei & (1LL << j))
29                     ws = ws * w[j] % MOD;
30             ret = (ret + ws * f_(rest & ~(1LL << i | cnei))) % MOD;
31         }
32         ret = (ret + w[i] * f_(rest ^ (1LL << i))) % MOD;
33         //printf("<%lld: %lld>
", rest, ret);
34         mp[rest] = ret;
35     }
36     return mp[rest];
37 }
38 
39 bool dfvis[N];
40 ll dfs_(int c) {
41     ll ret = 1LL << c;
42     for(int i = 0; i < n; ++i)
43         if(!dfvis[i] && tbl[c][i]) {
44             dfvis[i] = true;
45             ret |= 1L << i;
46             ret |= dfs_(i);
47         }
48     return ret;
49 }
50 
51 int main() {
52     int T;
53     scanf("%d", &T);
54     for(int it = 1; it <= T; ++it) {
55         memset(tbl, 0, sizeof tbl);
56         memset(dfvis, 0, sizeof dfvis);
57 
58         int m;
59         scanf("%d%d%lld", &n, &m, &MOD);
60         for(int i = 0; i < n; ++i)
61             scanf("%lld", w + i);
62         for(int i = 0; i < m; ++i) {
63             int a, b;
64             scanf("%d%d", &a, &b);
65             tbl[--a][--b] = true;
66             tbl[b][a] = true;
67         }
68 
69         for(int i = 0; i < n; ++i) {
70             nei[i] = 0;
71             for(int j = 0; j < n; ++j)
72                 if(i != j && tbl[i][j])
73                     nei[i] |= 1LL << j;
74         }
75 
76         ll ans = 1;
77         for(int i = 0; i < n; ++i)
78             if(!dfvis[i]) {
79                 ll blk = dfs_(i);
80                 mp.clear();
81                 ans = ans * f_(blk) % MOD;
82             }
83         printf("Case #%d: %lld
", it, ans);
84     }
85     return 0;
86 }
View Code

 

L 待补

M 待补

以上是关于2018 ACM-ICPC 宁夏邀请赛的主要内容,如果未能解决你的问题,请参考以下文章

[ICPC 2018 宁夏邀请赛] A-Maximum Element In A Stack(思维)

“2018宁夏邀请赛 ” 兼 “The 2019 Asia Yinchuan First Round Online Programming”

2018.5.19-20 ACM-ICPC2018 西安邀请赛 5/11 Rank40 Ag

ACM-ICPC 2018全国邀请赛(陕西西安)

gym101908 [2018-2019 ACM-ICPC Brazil Subregional Programming Contest] 题解

The 2019 ACM-ICPC China Shannxi Provincial Programming Contest (西安邀请赛重现) J. And And And