SWERC 2019-2020 做题记录

Posted uuzhateteee

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SWERC 2019-2020 做题记录相关的知识,希望对你有一定的参考价值。

A.

就是个带限制的最短路,多开一维状态(dis(i,j))表示到点(i),走的路程是(j)的最小值

注意各种细节就行了

技术图片
 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 struct Point
 4 {
 5     int x,y;
 6     Point(int X=0,int Y=0):x(X),y(Y){}
 7 }a[1005];
 8 int dist(int u,int v)
 9 {
10     return (int)(ceil(sqrt((a[u].x-a[v].x)*(a[u].x-a[v].x)+(a[u].y-a[v].y)*(a[u].y-a[v].y))));
11 }
12 int C[105];
13 int xs,ys,xd,yd,B,T;
14 int n;
15 vector< pair<int,int> > g[1005];
16 int dis[1005][105];
17 bool used[1005][105];
18 int main()
19 {
20     scanf("%d%d%d%d%d%d%d",&xs,&ys,&xd,&yd,&B,&C[0],&T);
21     for(int i=1;i<=T;++i)scanf("%d",&C[i]);
22     scanf("%d",&n);
23     a[0].x=xs;a[0].y=ys;a[n+1].x=xd;a[n+1].y=yd;
24     for(int i=1;i<=n;++i)
25     {
26         g[0].push_back(make_pair(i,C[0]));
27         g[i].push_back(make_pair(0,C[0]));
28         g[n+1].push_back(make_pair(i,C[0]));
29         g[i].push_back(make_pair(n+1,C[0]));
30     }
31     g[0].push_back(make_pair(n+1,C[0]));
32     g[n+1].push_back(make_pair(0,C[0]));
33     for(int i=1;i<=n;++i)
34     {
35         scanf("%d%d",&a[i].x,&a[i].y);
36         int k;
37         scanf("%d",&k);
38         while(k--)
39         {
40             int j,mj;
41             scanf("%d%d",&j,&mj);
42             j++;
43             g[i].push_back(make_pair(j,C[mj]));
44             g[j].push_back(make_pair(i,C[mj])); 
45         }
46     }
47     for(int u=0;u<=n+1;++u)
48     {
49         for(int i=0;i<g[u].size();++i)
50         {
51             int v=g[u][i].first,c=g[u][i].second;
52             g[u][i].second*=dist(u,v);
53         }
54     }
55     for(int i=0;i<=n+1;++i)
56         for(int j=0;j<=B;++j)dis[i][j]=1000000007;
57     priority_queue<pair<int,pair<int,int>>> q;
58     q.push(make_pair(0,make_pair(0,0)));
59     dis[0][0]=0;
60     while(!q.empty())
61     {
62         int u=q.top().second.first,k=q.top().second.second;
63         q.pop();
64         if(used[u][k])continue;
65         used[u][k]=1;
66         for(auto p:g[u])
67         {
68             int v=p.first,w=p.second;
69             int d=dist(u,v);
70             if(k+d>B)continue;
71             if(dis[v][k+d]>dis[u][k]+w)
72             {
73                 dis[v][k+d]=dis[u][k]+w;
74                 q.push(make_pair(-dis[v][k+d],make_pair(v,k+d)));
75             }
76         }
77     }
78     int ans=1000000007;
79     for(int i=0;i<=B;++i)ans=min(ans,dis[n+1][i]);
80     if(ans<1000000007)printf("%d
",ans);
81     else puts("-1");
82 }
View Code

 

B.

签到

技术图片
 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 int n;
 4 char s[22];
 5 map<string,int> mp; 
 6 int main()
 7 {
 8     scanf("%d",&n);
 9     bool yes=0;
10     for(int i=1;i<=n;++i)
11     {
12         scanf("%s",s);
13         mp[(string)s]++;
14         if(mp[s]>n/2)
15         {
16             yes=1;
17             printf("%s
",s);
18             break;
19         }
20     }
21     if(!yes)puts("NONE");
22 }
View Code

 

C.

签到

技术图片
 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 int n;
 4 int has[1000005]; 
 5 int main()
 6 {
 7     scanf("%d",&n);
 8     for(int i=1;i<=n;++i)
 9     {
10         int x;
11         scanf("%d",&x);
12         if(0<=x&&x<=n-1)has[x]=1;
13     }
14     for(int i=0;i<=n;++i)if(!has[i])
15     {
16         printf("%d
",i);
17         return 0;
18     }
19 }
View Code

 

F.

签到

技术图片
 1 #include<bits/stdc++.h> 
 2 #define ll long long
 3 using namespace std;
 4 struct Point
 5 {
 6     ll x,y;
 7     Point(ll x=0,ll y=0):x(x),y(y){}
 8 };
 9 typedef vector<Point> Polygon;
10 typedef Point Vector;
11 Vector operator + (Vector A,Vector B){return Vector(A.x+B.x,A.y+B.y);}
12 Vector operator - (Point A,Point B){return Vector(A.x-B.x,A.y-B.y);}
13 ll Cross(Vector A,Vector B){return A.x*B.y-A.y*B.x;}
14 ll PolygonArea(vector<Point> p)
15 {
16     int n=p.size();
17     ll area=0;
18     for(int i=1;i<n-1;++i)area+=Cross(p[i]-p[0],p[i+1]-p[0]);
19       return abs(area);
20 }
21 int n; 
22 int main()
23 {
24     scanf("%d",&n);
25     ll ans=0;
26     for(int i=1;i<=n;++i)
27     {
28         vector<Point> p;
29         p.clear(); 
30         int k;
31         scanf("%d",&k);
32         while(k--)
33         {
34             Point a;
35             scanf("%I64d%I64d",&a.x,&a.y);
36             p.push_back(a);
37         }
38         ans+=PolygonArea(p);
39     }
40     printf("%I64d
",ans/2);
41 }
View Code

 I.签到

技术图片
1 #include<bits/stdc++.h>
2 using namespace std;
3 int a,b,c;
4 int main(){
5     scanf("%d%d%d",&a,&b,&c);
6     int ans=(a+1)*(b+1)/(c+1)-1;
7     printf("%d
",ans);
8 }
View Code

 

J.

考虑在区间([l,r])中,如果有几个高度相同的最小高度的点,那以这几个为分界点把区间划开,剩下区间递归下去做,这几个点用卡特兰数算一下就行

然后我们考虑怎么找最小高度的点

每个点记录一个(next[i])表示和(a[i])高度相同的下一个位置

第一个点可以通过ST表找到,剩下点直接跳就行了

技术图片
 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 const int mod = 1000000007;
 4 int n;
 5 int a[1000005],nxt[1000005];
 6 vector<int> h[1000005];
 7 int st[1000005][21];
 8 int fac[2000005],inv[2000005];
 9 int fastpow(int a,int p)
10 {
11     int ans=1;
12     for(;p;p>>=1,a=1ll*a*a%mod)if(p&1)ans=1ll*ans*a%mod;
13     return ans;
14 }
15 int C(int x,int y)
16 {
17     return 1ll*fac[x]*inv[y]%mod*inv[x-y]%mod;
18 }
19 int Catalan(int x)
20 {
21     return 1ll*C(2*x,x)*fastpow(x+1,mod-2)%mod;
22 }
23 int query(int l,int r)
24 {
25     int k=log2(r-l+1);
26     if(a[st[l][k]]<=a[st[r-(1<<k)+1][k]])return st[l][k];
27     else return st[r-(1<<k)+1][k];
28 }
29 int solve(int l,int r)
30 {
31     if(l>=r)return 1;
32     int ans=1,cnt=1;
33     int i=query(l,r);
34     ans=1ll*ans*solve(l,i-1)%mod;
35     while(1)
36     {
37         if(nxt[i]<=r)
38         {
39             ans=1ll*ans*solve(i+1,nxt[i]-1)%mod;
40             cnt++;
41             i=nxt[i];
42         }
43         else
44         {
45             ans=1ll*ans*solve(i+1,r)%mod;
46             break;
47         }
48     }
49     ans=1ll*ans*Catalan(cnt)%mod;
50     return ans;
51 }
52 int main()
53 {
54     fac[0]=inv[0]=1;
55     for(int i=1;i<=2000000;++i)fac[i]=1ll*fac[i-1]*i%mod;
56     for(int i=1;i<=2000000;++i)inv[i]=fastpow(fac[i],mod-2);
57     scanf("%d",&n);
58     for(int i=1;i<=n;++i)
59     {
60         scanf("%d",&a[i]);
61         h[a[i]].push_back(i);
62     }
63     for(int i=0;i<=1000000;++i)h[i].push_back(n+1);
64     for(int i=0;i<=1000000;++i)
65         for(int j=0;j<h[i].size()-1;++j)nxt[h[i][j]]=h[i][j+1];
66     for(int i=1;i<=n;++i)st[i][0]=i;
67     for(int j=1;(1<<j)<=n;++j)
68         for(int i=1;i+(1<<j)-1<=n;++i)
69         {
70             if(a[st[i][j-1]]<=a[st[i+(1<<(j-1))][j-1]])st[i][j]=st[i][j-1];
71             else st[i][j]=st[i+(1<<(j-1))][j-1];
72         }
73     printf("%d
",solve(1,n));
74 }
View Code

 

K.

反向建图,考虑不直接连边时T点到所有相连点的可达性,因为若不通过直接连接的边,一定会通过另一与T直接相连的点

考虑对所有直接连接T的点二进制分组,一组连边一组不连,每次未连接的点若可达,则不满足题目要求

技术图片
 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 const int N=1e5+10;
 4 int n,m,t,vis[N],first[N],tot,cnt,ans[N],ansnum,flag[N];
 5 struct edge{
 6     int to,next,num;
 7 }e[N*2];
 8 void add(int u,int v){
 9     e[++tot].next=first[u],first[u]=tot;
10     e[tot].to=v;
11 }
12 void bfs(int x,int tp){
13     queue<int>q;
14     for(int i=first[t];i;i=e[i].next){
15         if((e[i].num&(1<<x))==(tp<<x)){
16             int u=e[i].to;
17             vis[u]=1;q.push(u);
18         }
19     }
20     while(!q.empty()){
21         int now=q.front();q.pop();
22         for(int i=first[now];i;i=e[i].next){
23             int u=e[i].to;
24             if(vis[u]||u==t)continue;
25             vis[u]=1;q.push(u);
26         }
27     }
28 }
29 int main(){
30     scanf("%d%d%d",&n,&m,&t);
31     for(int i=1,u,v;i<=m;i++){
32         scanf("%d%d",&u,&v);
33         add(v,u);
34         if(v==t){
35             e[tot].num=cnt++;flag[u]=1;
36         }
37     }
38     for(int i=0;(1<<i)<=cnt*4;i++){ 
39         memset(vis,0,sizeof(vis));
40         bfs(i,1);
41         for(int j=first[t];j;j=e[j].next){
42             int u=e[j].to;
43             if(vis[u]&&(e[j].num&(1<<i))==0){
44                 if(!ans[u])ans[u]=1,ansnum++;
45             }
46         }
47         memset(vis,0,sizeof(vis));
48         bfs(i,0);
49         for(int j=first[t];j;j=e[j].next){
50             int u=e[j].to;
51             if(vis[u]&&(e[j].num&(1<<i))){
52                 if(!ans[u])ans[u]=1,ansnum++;
53             }
54         }
55     }
56     printf("%d
",cnt-ansnum);
57     for(int i=0;i<n;i++)
58         if(!ans[i]&&flag[i])printf("%d
",i);
59 }
View Code

 

L.

我们把和每个湿地相连的连通块抠出来,这样的每个连通块大小不会超过(2n)

然后又因为每个这样的连通块是独立的,因此单独求SG最后异或一下就行了

求SG就状压一下然后记忆化搜索,注意判掉不合法的情况

技术图片
  1 #include<bits/stdc++.h>
  2 using namespace std;
  3 int n;
  4 char a[12][12];
  5 bool vis[12][12];
  6 int bel[12][12],now;
  7 struct Point
  8 {
  9     int x,y;
 10 }pos[22];
 11 int cnt;
 12 void dfs(int i,int j,int k)
 13 {
 14     if(vis[i][j])return;
 15     if(a[i][j]!=.)return;
 16     if(a[i-1][j]!=*&&a[i+1][j]!=*&&a[i][j-1]!=*&&a[i][j+1]!=*)return;
 17     if(bel[i][j]!=k)return;
 18     pos[cnt].x=i;pos[cnt].y=j;
 19     cnt++;
 20     vis[i][j]=1;
 21     dfs(i-1,j,k);dfs(i+1,j,k);dfs(i,j-1,k);dfs(i,j+1,k);
 22 }
 23 bool va(int S)
 24 {
 25     for(int i=0;i<cnt;++i)if(S&(1<<i))
 26         for(int j=i+1;j<cnt;++j)if(S&(1<<j))
 27         {
 28             if(pos[i].x==pos[j].x)
 29             {
 30                 if(pos[i].y==pos[j].y-1)
 31                 {
 32                     if(bel[pos[i].x][pos[i].y]==bel[pos[j].x][pos[j].y])return 0;
 33                 }
 34                 if(pos[i].y==pos[j].y+1)
 35                 {
 36                     if(bel[pos[i].x][pos[i].y]==bel[pos[j].x][pos[j].y])return 0;
 37                 }
 38             }
 39             else if(pos[i].y==pos[j].y)
 40             {
 41                 if(pos[i].x==pos[j].x-1)
 42                 {
 43                     if(bel[pos[i].x][pos[i].y]==bel[pos[j].x][pos[j].y])return 0;
 44                 }
 45                 if(pos[i].x==pos[j].x+1)
 46                 {
 47                     if(bel[pos[i].x][pos[i].y]==bel[pos[j].x][pos[j].y])return 0;
 48                 }
 49             }
 50         }
 51     return 1; 
 52 }
 53 int sg[1050000],has[1050000];
 54 int getsg(int S)
 55 {
 56     if(has[S])return sg[S];
 57     has[S]=1;
 58     int nxt[22];
 59     memset(nxt,0,sizeof(nxt));
 60     for(int i=0;i<cnt;++i)if(!(S&(1<<i)))
 61     {
 62         int sta=(S|(1<<i));
 63         if(va(sta))
 64         {
 65             int k=getsg(sta);
 66             nxt[k]=1;
 67         }
 68     }
 69     for(int i=0;i<=cnt;++i)if(!nxt[i])
 70     {
 71         sg[S]=i;
 72         break;
 73     }
 74     return sg[S];
 75 }
 76 int solve()
 77 {
 78     memset(has,0,sizeof(has));
 79     memset(sg,0,sizeof(sg));
 80     getsg(0);
 81     return sg[0];
 82 }
 83 const int dx[]={-1,0,1,0};
 84 const int dy[]={0,-1,0,1};
 85 int main()
 86 {
 87     scanf("%d",&n);
 88     for(int i=1;i<=n;++i)scanf("%s",a[i]+1);
 89     int ans=0;
 90     for(int i=1;i<=n;++i)
 91         for(int j=1;j<=n;++j)if(a[i][j]==*&&(!bel[i][j]))
 92         {
 93             bel[i][j]=++now;
 94             queue< pair<int,int> > q;
 95             q.push(make_pair(i,j));
 96             while(!q.empty())
 97             {
 98                 int x=q.front().first,y=q.front().second;
 99                 q.pop();
100                 for(int i=0;i<4;++i)
101                 {
102                     int nx=x+dx[i],ny=y+dy[i];
103                     if(bel[nx][ny])continue; 
104                     bel[nx][ny]=now;
105                     if(a[nx][ny]==*)q.push(make_pair(nx,ny));
106                 }
107             }
108         }
109     for(int i=1;i<=n;++i)
110         for(int j=1;j<=n;++j)if(a[i][j]==.&&(a[i-1][j]==*||a[i+1][j]==*||a[i][j-1]==*||a[i][j+1]==*)&&(!vis[i][j]))
111         {
112             cnt=0;
113             dfs(i,j,bel[i][j]);
114             ans^=solve();
115         }
116     if(ans)puts("First player will win");
117     else puts("Second player will win");
118 }
View Code

 

以上是关于SWERC 2019-2020 做题记录的主要内容,如果未能解决你的问题,请参考以下文章

2017 SWERC

bzoj 4439: [Swerc2015]Landscaping -- 最小割

buu学习记录(下)(做题是不可能做题的)

计算几何多边形面积——swerc Gym - 102501F

SWERC20054 values whose sum is 0

Codeforces Global Round 1 做题记录