0%

Codeforces Round #402 (Div. 1)

A. String Game 傻逼二分

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
#include<bits/stdc++.h>
#define maxn 200010
using namespace std;
char a[200010];
char b[200010];
char t[200010];
int c[200010];
int n;
int u;
bool pan(int x)
{
for(int i=1;i<=n;i++)
{
t[i]=a[i];
}
for(int i=1;i<=x;i++) t[c[i]]=-1;
int d=0;
for(int i=1;i<=n;i++)
{
if(t[i]==b[d+1]) d++;
if(d==u) return 1;
}
return 0;
}
int main()
{
scanf("%s",a+1);
scanf("%s",b+1);
n=strlen(a+1);
u=strlen(b+1);
for(int i=1;i<=n;i++)
{
scanf("%d",&c[i]);
}
int l,r;
l=0;
r=n;
while(l<r)
{
int mid=(l+r)/2+1;
if(pan(mid)==0) r=mid-1;
else l=mid;
}
printf("%d\n",l);
return 0;
}

B. Bitwise Formula 按位搜索即可

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
#include<bits/stdc++.h>
#define pb push_back
using namespace std;
int n,m;
char s[5010];
bool q[5010][1100];
bool qm[5010][1100];
string o[5010];
int tt[4];
int du[5010];
int yy[5010];
vector<int> e[5010];
int len;
map<string,int> ha;
int num;
int la;
string t;
int ff(bool t,int x)
{
int pp=0;
q[ha["?"]][x]=t;
queue<int> z;
for(int i=1;i<=num;i++)
{
if(du[i]==0) z.push(i);
}
while(!z.empty())
{
int w=z.front();
z.pop();
if(q[w][x]==1&&w!=ha["?"]) pp++;
for(auto &i:e[w])
{
du[i]--;
if(du[i]==0)
{
z.push(i);
if(o[i]=="XOR") q[i][x]^=q[w][x];
if(o[i]=="AND") q[i][x]&=q[w][x];
if(o[i]=="OR") q[i][x]|=q[w][x];

}
else q[i][x]=q[w][x];
}
}
return pp;
}
int main()
{
scanf("%d%d\n",&n,&m);
for(int i=1;i<=n;i++)
{
gets(s+1);
len=strlen(s+1);
int d=0;
bool oo=0;
for(int j=1;j<=len+1;j++)
{
if(s[j]==' '||j==len+1)
{
if(t[0]=='1'||t[0]=='0')
{
for(int k=0;k<m;k++)
{
q[la][k]=t[k]-'0';
}
}
else if(t!=":="&&t!="XOR"&&t!="AND"&&t!="OR")
{
if(ha[t]==0)
{
ha[t]=++num;
}
tt[++d]=ha[t];
if(oo==0) la=ha[t];
}
else if(t!=":=")
{
o[la]=t;
}
t="";
oo=1;
}
else t+=s[j];
}
if(d==3)
{
du[tt[1]]+=2;
e[tt[2]].pb(tt[1]);
e[tt[3]].pb(tt[1]);
}
}
int num1=0;
int num2=0;
for(int i=0;i<m;i++)
{
for(int j=1;j<=n+1;j++) yy[j]=du[j];
num1=ff(1,i);
for(int j=1;j<=n+1;j++) du[j]=yy[j];
num2=ff(0,i);
for(int j=1;j<=n+1;j++) du[j]=yy[j];
if(num1<num2) q[ha["?"]][i]=1;
else q[ha["?"]][i]=0;
if(num1>num2) qm[ha["?"]][i]=1;
else qm[ha["?"]][i]=0;
}
for(int i=0;i<m;i++) printf("%d",q[ha["?"]][i]);
printf("\n");
for(int i=0;i<m;i++) printf("%d",qm[ha["?"]][i]);
printf("\n");
return 0;
}

C. Peterson Polyglot 奇怪的trie树合并,写起来倒是很像暴力,但是复杂度似乎十分科学,目前还没有特别掌握证明方法。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
#include<bits/stdc++.h>
using namespace std;
int tr[300010][28];
bool v[300010];
int ans[300010];
int cnt;
int n;
int merge(int u,int v)
{
if(u==0||v==0) return u|v;
int ret=++cnt;
for(int i=0;i<26;i++)
{
tr[ret][i]=merge(tr[u][i],tr[v][i]);
}
return ret;
}
void tsm(int x)
{
cnt=n;
int rt=0;
for(int i=0;i<26;i++)
{
rt=merge(rt,tr[x][i]);
}
}
int dfs(int x,int dep)
{
tsm(x);
ans[dep+1]+=cnt-n+v[x];
for(int i=0;i<26;i++)
{
if(tr[x][i]) dfs(tr[x][i],dep+1);
}
}
int main()
{
scanf("%d",&n);
for(int i=1;i<n;i++)
{
int a,b;
char c[6];
scanf("%d%d%s",&a,&b,c);
tr[a][c[0]-'a']=b;
v[a]=1;
}
dfs(1,0);
int x=1;
for(int i=1;i<=n;i++)
{
if(n-ans[i]<n-ans[x]) x=i;
}
printf("%d\n%d\n",n-ans[x],x);
return 0;
}

D. Parquet Re-laying 类似于双向搜索? 将两个图都变成一个普通的形态(如一堆板子一直顺下来) 然后把操作合在一起就可以了。(其实感觉也不难?但比赛时候好像很少有人过?)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
#include<bits/stdc++.h>
#define pb push_back
#define eb emplace_back
using namespace std;
typedef pair<int,int> pii;
char s[55][55];
int n,m;
int getID(char t)
{
return t=='L'?0:t=='R'?1:t=='U'?2:3;
}
void dfs(vector<pii> &a,int x,int y,int tr)
{
if(s[x][y]==tr) return;
if(s[x][y]==0)
{
dfs(a,x+1,y,0);
a.eb(x,y);
s[x][y]=s[x][y+1]=2;
s[x+1][y]=s[x+1][y+1]=3;
return;
}
else
{
dfs(a,x,y+1,2);
a.eb(x,y);
s[x][y]=s[x+1][y]=0;
s[x][y+1]=s[x+1][y+1]=1;
return;
}
}
void solve(vector<pii> &a)
{
for(int i=1;i<=n;i++)
{
scanf("%s",s[i]+1);
for(int j=1;j<=m;j++) s[i][j]=getID(s[i][j]);
}
bool bj=0;
if(m&1)
{
bj=1;
swap(n,m);
for(int i=1;i<=max(n,m);i++)
{
for(int j=i+1;j<=max(n,m);j++)
{
swap(s[i][j],s[j][i]);
}
}
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
s[i][j]^=2;
}
}
}
for(int i=1;i<=n-1;i++)
{
for(int j=1;j<=m;j+=2)
{
dfs(a,i,j,0);
}
}
if(bj)
{
swap(n,m);
for(auto &i:a) swap(i.first,i.second);
}
}
int main()
{
scanf("%d%d",&n,&m);
vector<pii> a;
vector<pii> b;
solve(a);
solve(b);
for(int i=b.size()-1;i>=0;i--)
a.pb(b[i]);
printf("%d\n",(int)a.size());
for(auto &i:a)
{
printf("%d %d\n",i.first,i.second);
}
return 0;
}