# [The 2019 Asia Yinchuan First Round Online Programming]简要题解

### Maximum Element In A Stack

#### Code

#include <cstdio>
#include <cstring>
#include <algorithm>
#define fo(i,a,b) for(int i=a;i<=b;i++)
using namespace std;

typedef unsigned int u32;
typedef long long ll;

const int N=5e6+5;

int n,p,q,m,ty,ct,top;

u32 SA,SB,SC,mx[N];

u32 rng61() {
SA^=SA<<16;SA^=SA>>5;SA^=SA<<1;
u32 t=SA;
SA=SB;SB=SC;SC^=t^SA;
return SC;
}

void POP() {if (top) top--;}

void PUSH(u32 x) {
++top;
mx[top]=max(mx[top-1],x);
}

void gen() {
scanf("%d%d%d%d%u%u%u",&n,&p,&q,&m,&SA,&SB,&SC);
top=0;++ct;
ll ans=0;
fo(i,1,n) {
if (rng61()%(p+q)<p) PUSH(rng61()%m+1);
else POP();
ans^=(ll)i*mx[top];
}
printf("Case #%d: %lld\n",ct,ans);
}

int main() {
for(scanf("%d",&ty);ty;ty--) gen();
return 0;
}


### Rolling The Polygon

#### Code

#include <cmath>
#include <cstdio>
#include <cstring>
#include <algorithm>
#define fo(i,a,b) for(int i=a;i<=b;i++)
#define fd(i,a,b) for(int i=a;i>=b;i--)
using namespace std;

typedef double db;

const int N=55;

struct P{
db x,y;
P(db _x=0,db _y=0) {x=_x;y=_y;}
friend P operator + (P a,P b) {return P(a.x+b.x,a.y+b.y);}
friend P operator - (P a,P b) {return P(a.x-b.x,a.y-b.y);}
friend P operator * (P a,db b) {return P(a.x*b,a.y*b);}
friend db operator * (P a,P b) {return a.x*b.x+a.y*b.y;}
friend db operator ^ (P a,P b) {return a.x*b.y-a.y*b.x;}
}p[N],q;

db len(P a) {return sqrt(a*a);}

P rotate(P a,db b) {return P(a.x*cos(b)+a.y*sin(b),a.y*cos(b)-a.x*sin(b));}

db angle(P a) {return atan2(a.y,a.x);}

int n,ct;

void solve() {
++ct;
scanf("%d",&n);
fo(i,1,n) scanf("%lf%lf",&p[i].x,&p[i].y);scanf("%lf%lf",&q.x,&q.y);
fo(i,2,n) p[i].x-=p[1].x,p[i].y-=p[1].y;q.x-=p[1].x;q.y-=p[1].y;p[1].x=p[1].y=0;
db age=angle(p[2]);
fo(i,2,n) p[i]=rotate(p[i],age);q=rotate(q,age);
p[n+1]=p[1];p[n+2]=p[2];
db ans=0;
fo(i,2,n+1) {
P dir=p[i+1]-p[i];
db age=angle(dir);
fo(j,1,n+2) if (j!=i) p[j]=p[i]+rotate(p[j]-p[i],age);
q=p[i]+rotate(q-p[i],age);
ans+=fabs(age)*len(q-p[i]);
}
printf("Case #%d: %.3lf\n",ct,ans);
}

int main() {
int ty;
for(scanf("%d",&ty);ty;ty--) solve();
return 0;
}


### Caesar Cipher

#### Code

#include <cstdio>
#include <cstring>
#include <algorithm>
#define fo(i,a,b) for(int i=a;i<=b;i++)
#define fd(i,a,b) for(int i=a;i>=b;i--)
using namespace std;

const int N=55;

int n,m,ct;
char s[N],t[N],st[N];

void solve() {
ct++;
scanf("%d%d",&n,&m);
scanf("%s",s+1);scanf("%s",t+1);scanf("%s",st+1);
int shift=t[1]-s[1];if (shift<0) shift+=26;
printf("Case #%d: ",ct);
fo(i,1,m) putchar(st[i]-shift<'A'?st[i]-shift+26:st[i]-shift);
puts("");
}

int main() {
int ty;
for(scanf("%d",&ty);ty;ty--) solve();
return 0;
}


#### Code

#include <cstdio>
#include <cstring>
#include <algorithm>
#define fo(i,a,b) for(int i=a;i<=b;i++)
#define fd(i,a,b) for(int i=a;i>=b;i--)
using namespace std;

typedef double db;

const int N=55;

int n,m,ct;

void solve() {
ct++;
scanf("%d%d",&n,&m);
printf("Case #%d: %.6lf %.6lf\n",ct,n>1?0.5:1,(m+1)*1.0/(2*m));
}

int main() {
int ty;
for(scanf("%d",&ty);ty;ty--) solve();
return 0;
}


### Moving On

#### Solution

floyd求的就是只经过某些点的最短路

#### Code

#include <cstdio>
#include <cstring>
#include <algorithm>
#define fo(i,a,b) for(int i=a;i<=b;i++)
#define fd(i,a,b) for(int i=a;i>=b;i--)
using namespace std;

const int N=205,M=2e4+5;

int n,q,ct,w[N],d[N][N],ord[N],an[M];

bool cmp1(int x,int y) {return w[x]<w[y];}
bool cmp2(Que x,Que y) {return x.w<y.w;}

void solve() {
++ct;
scanf("%d%d",&n,&q);
fo(i,1,n) scanf("%d",&w[i]);
fo(i,1,n) fo(j,1,n) scanf("%d",&d[i][j]);
fo(i,1,n) ord[i]=i;
sort(ord+1,ord+n+1,cmp1);
fo(i,1,q) {
}
int j=0;
for(int l=1,r=0;l<=n;l=r+1) {
while (r<n&&w[ord[r+1]]==w[ord[l]]) r++;
j++;
}
fo(k,l,r) {
int x=ord[k];
fo(i,1,n) fo(j,1,n) if (i!=x&&j!=x&&i!=j) d[i][j]=min(d[i][j],d[i][x]+d[x][j]);
}
}
while (j<q) {
j++;
}
printf("Case #%d:\n",ct);
fo(i,1,q) printf("%d\n",an[i]);
}

int main() {
int ty;
for(scanf("%d",&ty);ty;ty--) solve();
return 0;
}


### Factories

#### Code

#include <cstdio>
#include <cstring>
#include <algorithm>
#define fo(i,a,b) for(int i=a;i<=b;i++)
#define fd(i,a,b) for(int i=a;i>=b;i--)
#define rep(i,a) for(int i=lst[a];i;i=nxt[i])
using namespace std;

typedef long long ll;

const int N=1e5+5;
const ll inf=1e18;

int t[N<<1],nxt[N<<1],v[N<<1],lst[N],l;
void add(int x,int y,int z) {t[++l]=y;v[l]=z;nxt[l]=lst[x];lst[x]=l;}

int n,K,ct,deg[N],sz[N];
ll f[N][105],g[105];

void Dp(int x,int y) {
rep(i,x) if (t[i]!=y) Dp(t[i],x);
fo(i,0,K) f[x][i]=inf;f[x][0]=sz[x]=0;
if (deg[x]==1) f[x][1]=0,sz[x]=1;
rep(i,x)
if (t[i]!=y) {
fo(j,0,min(K,sz[x]+sz[t[i]])) g[j]=inf;
fo(j,0,min(K,sz[x]))
fo(k,0,min(sz[t[i]],K-j))
g[j+k]=min(g[j+k],f[x][j]+f[t[i]][k]+v[i]*k*(K-k));
fo(j,0,min(K,sz[x]+sz[t[i]])) f[x][j]=g[j];
sz[x]+=sz[t[i]];
}
}

void solve() {
scanf("%d%d",&n,&K);++ct;
fo(i,1,n) lst[i]=deg[i]=0;l=0;
fo(i,1,n-1) {
int x,y,z;
scanf("%d%d%d",&x,&y,&z);
deg[x]++;deg[y]++;
}
printf("Case #%d: ",ct);
if (n==2) {
printf("%d\n",K==1?0:v[1]);
return;
}
fo(i,1,n)
if (deg[i]>1) {
Dp(i,0);
printf("%lld\n",f[i][K]);
return;
}
}

int main() {
int ty;
for(scanf("%d",&ty);ty;ty--) solve();
return 0;
}


### Fight Against Monsters

#### Code

#include <cmath>
#include <cstdio>
#include <cstring>
#include <algorithm>
#define fo(i,a,b) for(int i=a;i<=b;i++)
#define fd(i,a,b) for(int i=a;i>=b;i--)
using namespace std;

typedef long long ll;

const int N=1e5+5;

int n,ct;

struct Node{int t,a;}a[N];

bool cmp(Node a,Node b) {return (ll)a.t*b.a<(ll)b.t*a.a;}

void solve() {
scanf("%d",&n);++ct;
fo(i,1,n) {
scanf("%d%d",&a[i].t,&a[i].a);
int m=sqrt(2*a[i].t);
while (m*(m-1)>=2*a[i].t) m--;
while (m*(m+1)<2*a[i].t) m++;
a[i].t=m;
}
sort(a+1,a+n+1,cmp);
ll sum=0,ans=0;
fd(i,n,1) {
sum+=a[i].a;
ans+=sum*a[i].t;
}
printf("Case #%d: %lld\n",ct,ans);
}

int main() {
int ty;
for(scanf("%d",&ty);ty;ty--) solve();
return 0;
}


### Vertex Covers

#### Code

#include <vector>
#include <cstdio>
#include <cstring>
#include <algorithm>
#define fo(i,a,b) for(int i=a;i<=b;i++)
#define fd(i,a,b) for(int i=a;i>=b;i--)
#define pb(a) push_back(a)
#define mp(a,b) make_pair(a,b)
using namespace std;

typedef long long ll;

const int N=40,S=(1<<18)+5;

vector< pair<int,int> > A,B,C;

typedef vector< pair<int,int> > :: iterator it;

int n,m,Mo,ct,w[N],f[S];

void solve() {
scanf("%d%d%d",&n,&m,&Mo);ct++;
A.clear();B.clear();C.clear();
fo(i,1,n) scanf("%d",&w[i]);
int L=n>>1;
fo(s,0,(1<<L)-1) f[s]=0;
fo(i,1,m) {
int x,y;
scanf("%d%d",&x,&y);
if (x>y) swap(x,y);
if (y<=L) A.pb(mp(x,y));
else if (x>L) B.pb(mp(x-L,y-L));
else C.pb(mp(x,y-L));
}
fo(s,0,(1<<L)-1) {
bool ok=1;
for(it i=A.begin();i!=A.end();i++) {
int x=(*i).first,y=(*i).second;
if (!(s>>(x-1)&1)&&!(s>>(y-1)&1)) {ok=0;break;}
}
if (!ok) continue;
int ret=1;
fo(i,1,L) if (s>>(i-1)&1) ret=(ll)ret*w[i]%Mo;
f[s]=ret;
}
fo(i,0,L-1) fd(s,(1<<L)-1,0) if (s>>i&1) (f[s-(1<<i)]+=f[s])%=Mo;
int ans=0;
fo(s,0,(1<<n-L)-1) {
bool ok=1;
for(it i=B.begin();i!=B.end();i++) {
int x=(*i).first,y=(*i).second;
if (!(s>>(x-1)&1)&&!(s>>(y-1)&1)) {ok=0;break;}
}
if (!ok) continue;
int ret=1;
fo(i,1,n-L) if (s>>(i-1)&1) ret=(ll)ret*w[i+L]%Mo;
int t=0;
for(it i=C.begin();i!=C.end();i++) {
int x=(*i).first,y=(*i).second;
if (!(s>>(y-1)&1)) t|=1<<x-1;
}
(ans+=(ll)ret*f[t]%Mo)%=Mo;
}
printf("Case #%d: %d\n",ct,ans);
}

int main() {
int ty;
for(scanf("%d",&ty);ty;ty--) solve();
return 0;
}


### Continuous Intervals

#### Code

#include <map>
#include <cstdio>
#include <cstring>
#include <algorithm>
#define fo(i,a,b) for(int i=a;i<=b;i++)
#define fd(i,a,b) for(int i=a;i>=b;i--)
using namespace std;

typedef long long ll;

const int N=1e5+5;

struct Seg{int mn,cnt;}tr[N<<2];

int n,ct,tag[N<<2],a[N],sta_1[N],sta_2[N],top_1,top_2;
map<int,int> h;

Seg operator + (Seg x,Seg y) {
Seg z;
z.mn=min(x.mn,y.mn);z.cnt=0;
z.cnt+=(x.mn==z.mn)?x.cnt:0;
z.cnt+=(y.mn==z.mn)?y.cnt:0;
return z;
}

void build(int v,int l,int r) {
tr[v].mn=0;tr[v].cnt=r-l+1;tag[v]=0;
if (l==r) return;
int mid=l+r>>1;
build(v<<1,l,mid);
build(v<<1|1,mid+1,r);
}

void down(int v) {
if (tag[v]) {
tag[v]=0;
}
}

void modify(int v,int l,int r,int x,int y,int z) {
int mid=l+r>>1;down(v);
if (x<=mid) modify(v<<1,l,mid,x,y,z);
if (y>mid) modify(v<<1|1,mid+1,r,x,y,z);
tr[v]=tr[v<<1]+tr[v<<1|1];
}

void solve() {
scanf("%d",&n);h.clear();ct++;
fo(i,1,n) scanf("%d",&a[i]);
build(1,1,n);
ll ans=0;top_1=top_2=0;
fo(i,1,n) {
while (top_1&&a[sta_1[top_1]]<=a[i]) {
modify(1,1,n,sta_1[top_1-1]+1,sta_1[top_1],a[i]-a[sta_1[top_1]]);
top_1--;
}
sta_1[++top_1]=i;
while (top_2&&a[sta_2[top_2]]>=a[i]) {
modify(1,1,n,sta_2[top_2-1]+1,sta_2[top_2],a[sta_2[top_2]]-a[i]);
top_2--;
}
sta_2[++top_2]=i;
int la=h[a[i]]+1;h[a[i]]=i;
modify(1,1,n,la,i,-1);
if (tr[1].mn==-1) ans+=tr[1].cnt;
}
printf("Case #%d: %lld\n",ct,ans);
}

int main() {
int ty;
for(scanf("%d",&ty);ty;ty--) solve();
return 0;
}


### Acyclic Orientation

#### Solution

$F[n][m]=\sum_{i=1}^{m}F[n][m-i]*\binom{m}{i}*(-1)^{i+1}$

#### Code

#include <cmath>
#include <cstdio>
#include <cstring>
#include <algorithm>
#define fo(i,a,b) for(int i=a;i<=b;i++)
#define fd(i,a,b) for(int i=a;i>=b;i--)
using namespace std;

typedef long long ll;
typedef long double db;

const int N=(1<<18)+5,M=32767;

int n,m,ct,rev[N],fac[N],inv[N],f[N],g[N],a[N],b[N],c[N],Mo;

int pwr(int x,int y) {
int z=1;
for(;y;y>>=1,x=(ll)x*x%Mo)
if (y&1) z=(ll)z*x%Mo;
return z;
}

const db pi=acos(-1);

struct Com{
db r,i;
Com (db _r=0,db _i=0) {r=_r;i=_i;}
friend Com operator + (Com x,Com y) {return Com(x.r+y.r,x.i+y.i);}
friend Com operator - (Com x,Com y) {return Com(x.r-y.r,x.i-y.i);}
friend Com operator * (Com x,Com y) {return Com(x.r*y.r-x.i*y.i,x.r*y.i+x.i*y.r);}
}t1[N],t2[N],t3[N],t4[N];

Com conj(Com a) {return Com(a.r,-a.i);}

void DFT(Com *a,int len,int flag) {
fo(i,0,len-1) if (i<rev[i]) swap(a[i],a[rev[i]]);
for(int i=1;i<len;i<<=1) {
Com wn=Com(cos(pi/i),flag*sin(pi/i));
for(int j=0;j<len;j+=i<<1) {
Com w=Com(1,0);
for(int k=0;k<i;++k,w=w*wn) {
Com u=a[j+k],v=w*a[j+k+i];
a[j+k]=u+v;a[j+k+i]=u-v;
}
}
}
if (flag==-1) fo(i,0,len-1) a[i].r/=len,a[i].i/=len;
}

void mult(int *a,int *b,int *c,int n,int m,int l) {
int lg,len;
for(lg=0,len=1;len<=n+m;len<<=1) lg++;
fo(i,0,len-1) rev[i]=rev[i>>1]>>1|((i&1)<<(lg-1));
fo(i,0,len-1) t1[i]=t2[i]=t3[i]=t4[i]=Com(0,0);
fo(i,0,n) t1[i]=Com(a[i]&M,a[i]>>15);
fo(i,0,m) t2[i]=Com(b[i]&M,b[i]>>15);
DFT(t1,len,1);DFT(t2,len,1);
fo(i,0,len-1) {
int j=(len-i)&(len-1);
Com da=(t1[i]+conj(t1[j]))*Com(0.5,0);// a%r
Com db=(t1[i]-conj(t1[j]))*Com(0,-0.5);// a/r
Com dc=(t2[i]+conj(t2[j]))*Com(0.5,0);// b%r
Com dd=(t2[i]-conj(t2[j]))*Com(0,-0.5);// b/r
t3[i]=da*dc+da*dd*Com(0,1);
t4[i]=db*dc+db*dd*Com(0,1);
}
DFT(t3,len,-1);DFT(t4,len,-1);
fo(i,0,l) {
int ka=(ll)(t3[i].r+0.5)%Mo,kb=(ll)(t3[i].i+0.5)%Mo;
int kc=(ll)(t4[i].r+0.5)%Mo,kd=(ll)(t4[i].i+0.5)%Mo;
c[i]=((ll)ka+((ll)(kb+kc)<<15)+((ll)kd<<30))%Mo;
}
}

void solve() {
scanf("%d%d%d",&n,&m,&Mo);ct++;
fo(i,0,n+m) f[i]=g[i]=a[i]=b[i]=c[i]=0;
fac[0]=1;fo(i,1,m+n) fac[i]=(ll)fac[i-1]*i%Mo;
inv[m+n]=pwr(fac[m+n],Mo-2);fd(i,m+n-1,0) inv[i]=(ll)inv[i+1]*(i+1)%Mo;
fo(i,0,max(n,m)) g[i]=inv[i];
fo(i,0,n) f[i]=(ll)inv[i]*pwr(-i,n)%Mo*(i&1?1:-1),(f[i]+=Mo)%=Mo;
mult(f,g,a,n,n,n);
fo(i,0,m) f[i]=(ll)inv[i]*pwr(-i,m)%Mo*(i&1?1:-1),(f[i]+=Mo)%=Mo;
mult(f,g,b,m,m,m);
a[0]=b[0]=0;mult(a,b,c,n,m,n+m);
int ans=0;
fo(i,1,n+m) (ans+=(ll)c[i]*fac[i]%Mo)%=Mo;
printf("Case #%d: %d\n",ct,(ans+Mo)%Mo);
}

int main() {
int ty;
for(scanf("%d",&ty);ty;ty--) solve();
return 0;
}


### 后记

12-06 267

11-30 937

08-31 134

08-31 51

09-02 97

08-31 126

09-02 169

05-18 59

08-31 44

05-19 59

#### 2019 ICPC Asia Yinchuan Regional H

©️2020 CSDN 皮肤主题: 编程工作室 设计师: CSDN官方博客

1.余额是钱包充值的虚拟货币，按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载，可以购买VIP、C币套餐、付费专栏及课程。