# BOI2020 DAY2

## 前言

BOI还是原来的味道。。好难。。但是看到好多人当场AK了。。果然是我太菜了吗。。

## A Graph

### $Code$

#include<bits/stdc++.h>
#define LL long long
#define ull unsigned long long
#define LL long long
using namespace std;
const int N=2e5+10;
const int M=3e5+10;
int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
void print(LL x){
if(x>9) print(x/10);
putchar(x%10+'0');
}
int n,m,cnt=1;
struct edge{
int r,nxt;
int c;
}e[M<<1];
int a[N],b[N];
double ans[N],X;
int vis[N],vis2[N],hed[N];
bool f,youjie;
void insert(int u,int v,int c){
e[++cnt].r=v;e[cnt].c=c;e[cnt].nxt=hed[u];hed[u]=cnt;
}
void J(int A,int B,int c){
c=c-B;
if((!A)&&(!c)) return;
if(!A) {youjie=0;return;}
double y=(double)c/(double)A;
if((!f)||y==X) {X=y;f=1;return;}
youjie=0;return;
}

int q[N];int top;
void dfs(int u){
int v;
for(int i=hed[u];i&&youjie;i=e[i].nxt){
v=e[i].r;
if(!vis[v]){
vis[v]=1;
a[v]=-a[u];
b[v]=e[i].c-b[u];
q[++top]=-a[v]*b[v];
dfs(v);
}
else{
J(a[u]+a[v],b[u]+b[v],e[i].c);
}
}
}
void getans(int u){
ans[u]=(double)a[u]*X+(double)b[u];
for(int i=hed[u];i;i=e[i].nxt)
if(!vis2[e[i].r]) {
vis2[e[i].r]=1;
getans(e[i].r);
}
}
int main(){
int u,v,c;
scanf("%d%d",&n,&m);
for(int i=1;i<=m;++i){
scanf("%d%d%d",&u,&v,&c);
insert(u,v,c);insert(v,u,c);
}
bool flag=1;
for(int i=1;i<=n;++i){
if(vis[i]) continue;
a[i]=1;b[i]=0;f=0;youjie=1;vis[i]=1;top=1;q[1]=0;
dfs(i);
if(!youjie) {
flag=0;
break;
}

if(!f){
sort(q+1,q+1+top);
X=q[(top+1)/2];
}
vis2[i]=1;
getans(i);
}
if(!flag) printf("NO\n");
else {
printf("YES\n");
for(int i=1;i<=n;++i) cout<<ans[i]<<" ";
puts("");
}
return 0;
}


## B1 Village

### $Code$

#include<bits/stdc++.h>
#define LL long long
#define ull unsigned long long
#define LL long long
using namespace std;
const int N=3e5+10;
int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
void print(LL x){
if(x>9) print(x/10);
putchar(x%10+'0');
}
int n,cnt=1;
struct edge{
int r,nxt;
}e[N];
int hed[N];
void insert(int u,int v){
e[++cnt].r=v;e[cnt].nxt=hed[u];hed[u]=cnt;
}
LL ans=0;
int p[N],fa[N];
void dfs(int u){
for(int i=hed[u];i;i=e[i].nxt){
if(e[i].r==fa[u])continue;
fa[e[i].r]=u;
dfs(e[i].r);
}
if(p[u]==u&&fa[u]){
ans+=2;
swap(p[u],p[fa[u]]);
}
}
int main(){
int u,v;
scanf("%d",&n);
for(int i=1;i<n;++i){
scanf("%d%d",&u,&v);
insert(u,v);insert(v,u);
}
for(int i=1;i<=n;++i) p[i]=i;
dfs(1);
if(p[1]==1) {
v=e[hed[1]].r;
ans+=2;
swap(p[1],p[v]);
}
printf("%I64d\n",ans);
for(int i=1;i<=n;++i) printf("%d ",p[i]);puts("");
return 0;
}


## B2 Village

### $Code$

#include<bits/stdc++.h>
#define LL long long
#define ull unsigned long long
#define LL long long
using namespace std;
const int N=3e5+10;
int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
void print(LL x){
if(x>9) print(x/10);
putchar(x%10+'0');
}
int n,cnt=1,rt;
struct edge{
int r,nxt;
}e[N];
int hed[N];
void insert(int u,int v){
e[++cnt].r=v;e[cnt].nxt=hed[u];hed[u]=cnt;
}
bool vis[N];
int siz[N],son[N];
LL ans=0;
void dfs(int u){
vis[u]=1;siz[u]=1;
for(int i=hed[u];i;i=e[i].nxt){
if(vis[e[i].r]) continue;
dfs(e[i].r);
siz[u]+=siz[e[i].r];
if(siz[e[i].r]>siz[son[u]]) son[u]=e[i].r;
}
}
int fa[N];
void getans(int u){
siz[u]=1;
for(int i=hed[u];i;i=e[i].nxt)
if(fa[u]!=e[i].r){
fa[e[i].r]=u;
getans(e[i].r);
siz[u]+=siz[e[i].r];
if(siz[e[i].r]>siz[son[u]]) son[u]=e[i].r;
ans=ans+(LL)2*(LL)min(siz[e[i].r],n-siz[e[i].r]);
}
}
vector<int> ve;
bool cmp(int A,int B){return siz[A]>siz[B];}
int t1=0,t2=0;
int p1[N],p2[N],p[N];
void dfs2(int u,int *p,int &top){
p[++top]=u;
for(int i=hed[u];i;i=e[i].nxt)
if(fa[u]!=e[i].r) dfs2(e[i].r,p,top);
}
int main(){
int u,v;
scanf("%d",&n);
for(int i=1;i<n;++i){
scanf("%d%d",&u,&v);
insert(u,v);insert(v,u);
}
dfs(1);
for(int i=1;i<=n;++i){
u=max(siz[son[i]],n-siz[i]);
if(u<=(n/2)) {rt=i;break;}
}
memset(siz,0,sizeof(siz));
memset(son,0,sizeof(son));
getans(rt);
printf("%I64d\n",ans);
for(int i=hed[rt];i;i=e[i].nxt) ve.push_back(e[i].r);
sort(ve.begin(),ve.end(),cmp);
for(int i=0;i<ve.size();++i) dfs2(ve[i],p1,t1);
p1[++t1]=rt;
for(int i=1;i<ve.size();++i) dfs2(ve[i],p2,t2);
p2[++t2]=rt;dfs2(ve[0],p2,t2);
for(int i=1;i<=t1;++i) p[p1[i]]=p2[i];
for(int i=1;i<=n;++i) printf("%d ",p[i]);puts("");
return 0;
}


## C Viruses

### 输入格式：

$G>2$ , $N\geq G-2$ , $M\geq 0$ , $2\leq a<G$ , $k\geq 1$ , $0\geq b_i<G$ , $l>0$ , $0\leq c_i\leq 1$ , $\sum{k}\leq 100$ , $\sum{l}\leq 50$

### 输出格式

$G-2$ 行第 $i$ 行代表 $i$ 基因以及其所有变异到的基因是否都可以被任意一组抗体检测到，如果可以，输出一个字符串 $YES$，如果不可以，首先一个字符串 $NO$，接下来一个整数代表不能检测到的基因中的最短长度。

### $Code（M=1）$

#include<bits/stdc++.h>
#define LL long long
#define ull unsigned long long
using namespace std;
const int N=103;
const int S=53;
const ull INF = -1;

int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
void print(LL x){
if(x>9) print(x/10);
putchar(x%10+'0');
}

int G,n,m;
int a[N],k[N],b[N][N];
int l[S],c[S][S];
ull dp[N][S][S];
ull tp[S][S];
int cnt;

int nxt[S],go[S][2];
void KMP(int len,int *s){
int j=0;
for(int i=2;i<=len;++i){
while(j>0&&s[j+1]!=s[i]) j=nxt[j];
if(s[j+1]==s[i]) ++j;
nxt[i]=j;
}
go[len][0]=go[len][1]=len;
for(int i=0;i<len;++i){
for(int h=0;h<=1;++h){
if(h==s[i+1]) go[i][h]=i+1;
else go[i][h]=go[nxt[i]][h];
}
}
}
bool sol(int row){
bool re=0;
for(int st=0;st<=cnt;++st){
fill_n(tp[0],S*S,INF);
tp[0][st]=0;
for(int it=1;it<=k[row];++it){
int h=b[row][it];
for(int i=0;i<=cnt;++i){
if(tp[it-1][i]>=INF)
continue;
for(int j=0;j<=cnt;++j)
if(dp[h][i][j]<INF)
tp[it][j]=min(tp[it][j],tp[it-1][i]+dp[h][i][j]);
}
}
for(int ed=0;ed<=cnt;++ed){
if(dp[a[row]][st][ed]>tp[k[row]][ed]){
dp[a[row]][st][ed]=tp[k[row]][ed];
re=1;
}
}
}
return re;
}
int main(){
scanf("%d%d%d",&G,&n,&m);
for(int i=1;i<=n;++i){
scanf("%d%d",&a[i],&k[i]);
for(int j=1;j<=k[i];++j){
scanf("%d",&b[i][j]);
}
}
for(int i=1;i<=m;++i){
scanf("%d",&l[i]);
for(int j=1;j<=l[i];++j){
scanf("%d",&c[i][j]);
}
}
KMP(l[1],c[1]);
cnt=l[1];
fill_n(dp[0][0],N*S*S,INF);
for(int i=0;i<=cnt;++i){
for(int h=0;h<=1;++h){
dp[h][i][go[i][h]]=1;
}
}
int flag=1,it=0;
for(;flag&&it<G-2;++it){
flag=0;
for(int i=1;i<=n;++i) flag|=sol(i);
}
for(int i=2;i<G;++i) {
ull ans=INF;
for(int j=0;j<cnt;++j)
ans=min(ans,dp[i][0][j]);
if(ans<INF) cout<<"NO " <<ans<<endl;
else cout<<"YES"<<endl;
}
return 0;
}


### $Code$

#include<bits/stdc++.h>
#define LL long long
#define ull unsigned long long
using namespace std;
const int N=103;
const int S=55;
const ull INF = -1;

int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
void print(LL x){
if(x>9) print(x/10);
putchar(x%10+'0');
}

int G,n,m;
int a[N],k[N],b[N][N];
int l[S],c[S][S];
ull dp[N][S][S];
ull tp[S][S];
int cnt;
queue<int>q;
struct ACauto{
int t[S][2],val[S],fail[S];
void ins(int len,int *s){
int now=0;
for(int i=1;i<=len;i++){
int v=s[i];
if(!t[now][v]) t[now][v]=++cnt;
now=t[now][v];
}
val[now]++;
}
void build(){
for(int i=0;i<2;i++)
if(t[0][i]) {
fail[t[0][i]]=0;
q.push(t[0][i]);
}
while(!q.empty()){
int u=q.front();q.pop();
for(int i=0;i<2;i++) {
if(t[u][i]) {
fail[t[u][i]]=t[fail[u]][i];
q.push(t[u][i]);
}
else t[u][i]=t[fail[u]][i];
}
}
for(int j=0;j<=cnt;++j){
int flag=val[j],i=j;
while(i){
i=fail[i];
flag=max(flag,val[i]);
}
val[j]=flag;
if(val[j]) t[j][0]=t[j][1]=j;
}
}
}AC;

bool sol(int row){
bool re=0;
for(int st=0;st<=cnt;++st){
fill_n(tp[0],S*S,INF);
tp[0][st]=0;
for(int it=1;it<=k[row];++it){
int h=b[row][it];
for(int i=0;i<=cnt;++i){
if(tp[it-1][i]>=INF)
continue;
for(int j=0;j<=cnt;++j)
if(dp[h][i][j]<INF)
tp[it][j]=min(tp[it][j],tp[it-1][i]+dp[h][i][j]);
}
}
for(int ed=0;ed<=cnt;++ed){
if(dp[a[row]][st][ed]>tp[k[row]][ed]){
dp[a[row]][st][ed]=tp[k[row]][ed];
re=1;
}
}
}
return re;
}
int main(){
scanf("%d%d%d",&G,&n,&m);
for(int i=1;i<=n;++i){
scanf("%d%d",&a[i],&k[i]);
for(int j=1;j<=k[i];++j){
scanf("%d",&b[i][j]);
}
}
for(int i=1;i<=m;++i){
scanf("%d",&l[i]);
for(int j=1;j<=l[i];++j){
scanf("%d",&c[i][j]);
}
AC.ins(l[i],c[i]);
}
AC.build();
fill_n(dp[0][0],N*S*S,INF);
for(int i=0;i<=cnt;++i){
for(int h=0;h<2;++h){
dp[h][i][AC.t[i][h]]=1;
}
}
int flag=1,it=0;
for(;flag&&it<G-2;++it){
flag=0;
for(int i=1;i<=n;++i) flag|=sol(i);
}
for(int i=2;i<G;++i) {
ull ans=INF;
for(int j=0;j<=cnt;++j)
if(!AC.val[j]){
ans=min(ans,dp[i][0][j]);
}
if(ans<INF) cout<<"NO " <<ans<<endl;
else cout<<"YES"<<endl;
}
return 0;
}

posted @ 2020-07-27 17:18  Iscream-2001  阅读(203)  评论(0编辑  收藏  举报
/* */