# Codeforces Round #483 (Div. 1) 简要题解

A. Finite or not?

#include<bits/stdc++.h>
using namespace std;
#define ll long long
{
ll 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;
}
inline ll gcd(ll x,ll y){return y?gcd(y,x%y):x;}
int main()
{
{
ll g=gcd(p,q),c;p/=g;q/=g;
while((g=gcd(q,b))>1)
do q/=g; while(q%g==0);
puts(q>1?"Infinite":"Finite");
}
return 0;
}

#include<bits/stdc++.h>
using namespace std;
#define ll long long
{
ll 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;
}
inline ll gcd(ll x,ll y){return y?gcd(y,x%y):x;}
inline ll mul(ll x,ll mod){return ((x*x-(ll)((long double)x*x/mod)*mod)%mod+mod)%mod;}
int main()
{
{
q/=gcd(p,q);b%=q;
for(int i=1;i<=6&&b;++i) b=mul(b,q);
puts(b?"Infinite":"Finite");
}
return 0;
}


B. XOR-pyramid

#include<bits/stdc++.h>
#define MN 5000
using namespace std;
{
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;
}
int f[MN+5][MN+5],n,Q,mx[MN+5][MN+5];
int main()
{
for(int i=n;i;--i) for(int j=i+1;j<=n;++j)
f[i][j]=f[i][j-1]^f[i+1][j],mx[i][j]=max(f[i][j],max(mx[i+1][j],mx[i][j-1]));
return 0;
}


C. Elevator

#include<bits/stdc++.h>
#define MN 2000
#define MX 720
using namespace std;
{
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;
}
int ans=1e9,n,a[MN+5],b[MN+5],cnt,num[MX+5],A[6],c[MX+5][5];
int id[10][10][10][10],f[15000005],q[15000005],top;
void dfs(int x,int v)
{
++cnt;num[cnt]=x-1;id[A[1]][A[2]][A[3]][A[4]]=cnt;
for(int j=1;j<x;++j) c[cnt][j]=A[j];
if(x>4)return;
for(int i=v;i<=9;++i) A[x]=i,dfs(x+1,i);
A[x]=0;
}
inline int ID(int x,int y,int z){return x*MX*10+y*10+z;}
void Try(int x,int y,int z,int v)
{
int d=ID(x,y,z);
if(v<f[d]) f[q[++top]=d]=v;
}
int main()
{
dfs(1,1);memset(f,40,sizeof(f));
f[q[top=1]=ID(0,id[0][0][0][0],1)]=0;
for(int i=1;i<=top;++i)
{
int x=q[i]/MX/10,y=(q[i]/10)%MX,z=q[i]%10,v=f[q[i]];
if(z<9) Try(x,y,z+1,v+1);
if(z>1) Try(x,y,z-1,v+1);
int nn=0;
for(int j=1;j<=num[y];++j)
if(c[y][j]!=z) A[++nn]=c[y][j];
for(int j=nn+1;j<=4;++j) A[j]=0;
Try(x,id[A[1]][A[2]][A[3]][A[4]],z,v+(num[y]-nn));
if(x<n&&a[x+1]==z&&num[y]<4)
{
int nn=0,k=1;
for(;k<=num[y];++k)
if(c[y][k]<=b[x+1]) A[++nn]=c[y][k];
else break;
A[++nn]=b[x+1];
for(;k<=num[y];++k) A[++nn]=c[y][k];
while(nn<4) A[++nn]=0;
Try(x+1,id[A[1]][A[2]][A[3]][A[4]],z,v+1);
}
}
for(int i=1;i<=9;++i) ans=min(ans,f[ID(n,id[0][0][0][0],i)]);
cout<<ans;
return 0;
}


#pragma GCC optimize("Ofast")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
#include<bits/stdc++.h>
#define MN 100000
#define G() st[x].lower_bound((Li){L,0,0})
using namespace std;
{
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;
}
struct Rec{int x1,y1,x2,y2;}s[MN+5];
int n,Lx[MN*2+5],Ly[MN*2+5],numx,numy,ans,vis[MN+5],B,C,cnt,rt[55];
struct Li{int l,r,v;}a[MN+5],b[MN+5],c[MN+5];
struct Tree{int l,r,mx,x;short d;}T[4000005];
struct cmp{bool operator()(const Li&a,const Li&b){return a.l==b.l?(a.r==b.r?a.v<b.v:a.r<b.r):a.l<b.l;}};
set<Li,cmp> st[524295];set<Li,cmp>::iterator it;
void Ins(int x,int lt,int rt,int l,int r,int L,int R,int now)
{
if(l==lt&&r==rt)
{
it=G();
if(it!=st[x].begin())
{
--it;Li y=*it;
if(it->r>R)
{
st[x].erase(it);
st[x].insert((Li){y.l,L-1,y.v});
st[x].insert((Li){R+1,y.r,y.v});
}
else if(it->r>=L)
{
st[x].erase(it);
st[x].insert((Li){y.l,L-1,y.v});
}
}
for(it=G();it->l<=R;it=G())
{
Li y=*it;st[x].erase(it);
if(y.r>R) st[x].insert((Li){R+1,y.r,y.v});
}
st[x].insert((Li){L,R,now});
return;
}
int mid=lt+rt>>1;
if(r<=mid) Ins(x<<1,lt,mid,l,r,L,R,now);
else if(l>mid) Ins(x<<1|1,mid+1,rt,l,r,L,R,now);
else Ins(x<<1,lt,mid,l,mid,L,R,now),Ins(x<<1|1,mid+1,rt,mid+1,r,L,R,now);
}
void Build(int x,int l,int r)
{
if(st[x].insert((Li){1,numy,0}),l==r) return;
int mid=l+r>>1;
Build(x<<1,l,mid);Build(x<<1|1,mid+1,r);
}
int now_dep;
inline int newnode(int x){return T[x].d==now_dep?x:(T[++cnt]=T[x],T[cnt].d=now_dep,cnt);}
inline void update(int x){T[x].mx=max(T[x].x,min(T[T[x].l].mx,T[T[x].r].mx));}
void Modify(int x,int lt,int rt,int l,int r,int v)
{
if(lt==l&&rt==r){T[x].x=max(T[x].x,v);T[x].mx=max(T[x].mx,v);return;}
int mid=lt+rt>>1;
if(r<=mid) Modify(T[x].l=newnode(T[x].l),lt,mid,l,r,v);
else if(l>mid) Modify(T[x].r=newnode(T[x].r),mid+1,rt,l,r,v);
else Modify(T[x].l=newnode(T[x].l),lt,mid,l,mid,v),
Modify(T[x].r=newnode(T[x].r),mid+1,rt,mid+1,r,v);
update(x);
}
int Query(int x,int lt,int rt,int l,int r)
{
if(!x) return 0;
if(lt==l&&rt==r) return T[x].mx;
int mid=lt+rt>>1;
if(r<=mid) return max(Query(T[x].l,lt,mid,l,r),T[x].x);
else if(l>mid) return max(Query(T[x].r,mid+1,rt,l,r),T[x].x);
else return max(T[x].x,min(Query(T[x].l,lt,mid,l,mid),Query(T[x].r,mid+1,rt,mid+1,r)));
}
void Solve(int x,int l,int r,int dep)
{
if(l==r)
{
for(it=st[x].begin();it!=st[x].end();++it)
if(Query(rt[dep-1],1,numy,it->l,it->r)<=it->v)
if(!vis[it->v]) vis[it->v]=1,++ans;
return;
}
now_dep=dep;
int mid=l+r>>1,A=0,L=x<<1,R=L|1,precnt=cnt;
rt[dep]=newnode(rt[dep-1]);
for(it=st[x].begin();it!=st[x].end();++it) Modify(rt[dep],1,numy,it->l,it->r,it->v);
Solve(L,l,mid,dep+1);Solve(R,mid+1,r,dep+1);B=C=0;
for(it=st[x].begin();it!=st[x].end();++it) a[++A]=*it;
st[x].clear();
for(it=st[L].begin();it!=st[L].end();++it) b[++B]=*it;st[L].clear();
for(it=st[R].begin();it!=st[R].end();++it) c[++C]=*it;st[R].clear();
for(int i=1,j=1,k=1;i<=A;++i)
{
int ok=0;
while(j<=B&&b[j].r<a[i].l) ++j;
while(k<=C&&c[k].r<a[i].l) ++k;
while(j>1&&b[j-1].r>=a[i].l) --j;
while(k>1&&c[k-1].r>=a[i].l) --k;
for(int last=a[i].l-1;!ok&&last<a[i].r;)
{
int v=min(b[j].v,c[k].v),rr=min(b[j].r,c[k].r);
if(v<=a[i].v&&Query(rt[dep],1,numy,last+1,min(rr,a[i].r))<=a[i].v) ok=1;
last=rr;
if(b[j].r==rr) ++j;
if(c[k].r==rr) ++k;
}
if(ok&&!vis[a[i].v]) vis[a[i].v]=1,++ans;
}
if(x==1) return;
for(int i=1,j=1,k=1,last=0;i<=A;)
{
int v=max(a[i].v,min(b[j].v,c[k].v)),rr=min(a[i].r,min(b[j].r,c[k].r));
st[x].insert((Li){last+1,rr,v});last=rr;
if(a[i].r==rr) ++i;
if(b[j].r==rr) ++j;
if(c[k].r==rr) ++k;
}
cnt=precnt;
}
int main()
{
for(int i=1;i<=n;++i)
{
Lx[++numx]=s[i].x1;Lx[++numx]=s[i].x2;
Ly[++numy]=s[i].y1;Ly[++numy]=s[i].y2;
}
sort(Lx+1,Lx+numx+1);numx=unique(Lx+1,Lx+numx+1)-Lx-1;
sort(Ly+1,Ly+numy+1);numy=unique(Ly+1,Ly+numy+1)-Ly-1;
Build(1,1,numx);
for(int i=1;i<=n;++i)
{
s[i].x1=lower_bound(Lx+1,Lx+numx+1,s[i].x1)-Lx;
s[i].x2=lower_bound(Lx+1,Lx+numx+1,s[i].x2)-Lx-1;
s[i].y1=lower_bound(Ly+1,Ly+numy+1,s[i].y1)-Ly;
s[i].y2=lower_bound(Ly+1,Ly+numy+1,s[i].y2)-Ly-1;
Ins(1,1,numx,s[i].x1,s[i].x2,s[i].y1,s[i].y2,i);
}
Solve(1,1,numx,1);
printf("%d\n",ans);
return 0;
}


E. NN country

#include<bits/stdc++.h>
#define MN 200000
#define MD 18
using namespace std;
{
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;
}
vector<int> v[MN+5],V[MN+5];
int n,m,Q,fa[MD+1][MN+5],f[MD+1][MN+5],dep[MN+5],rt[MN+5],dfn[MN+5],dn,p[MN+5],nr[MN+5],cnt;
struct Tree{int l,r,x;}T[12000005];
inline int lca(int x,int y)
{
if(dep[x]<dep[y]) swap(x,y);
for(int k=dep[x]-dep[y],j=0;k;k>>=1,++j)
if(k&1) x=fa[j][x];
if(x==y)return x;
for(int i=MD;~i;--i) if(fa[i][x]!=fa[i][y]) x=fa[i][x],y=fa[i][y];
return fa[0][x];
}
void dfs(int x)
{
dfn[x]=++dn;p[dn]=x;
for(int i=0;i<v[x].size();++i) dfs(v[x][i]);
nr[x]=dn;
}
int Query(int x,int l,int r,int lt=1,int rt=n)
{
if(!x||(l==lt&&r==rt))return T[x].x;
int mid=lt+rt>>1;
if(r<=mid) return Query(T[x].l,l,r,lt,mid);
else if(l>mid) return Query(T[x].r,l,r,mid+1,rt);
else return Query(T[x].l,l,mid,lt,mid)+Query(T[x].r,mid+1,r,mid+1,rt);
}
inline int newnode(int x){T[++cnt]=T[x];return cnt;}
void Modify(int x,int l,int r,int k)
{
if(++T[x].x,l==r) return;
int mid=l+r>>1;
if(k<=mid) Modify(T[x].l=newnode(T[x].l),l,mid,k);
else Modify(T[x].r=newnode(T[x].r),mid+1,r,k);
}
inline int Min(int x,int y){return dep[x]<dep[y]?x:y;}
int main()
{
for(int i=1;i<=n;++i) f[0][i]=i;dfs(1);
for(int i=1;i<=MD;++i) for(int j=1;j<=n;++j) fa[i][j]=fa[i-1][fa[i-1][j]];
for(int i=1;i<=m;++i)
{
f[0][x]=Min(f[0][x],z);
f[0][y]=Min(f[0][y],z);
if(dfn[x]>dfn[y]) swap(x,y);
V[y].push_back(x);
}
for(int i=1;i<=n;++i)
{
rt[i]=newnode(rt[i-1]);
for(int j=0;j<V[p[i]].size();++j)
Modify(rt[i],1,n,dfn[V[p[i]][j]]);
}
for(int i=n;i;--i) f[0][fa[0][i]]=Min(f[0][fa[0][i]],f[0][i]);
for(int i=1;i<=MD;++i) for(int j=1;j<=n;++j) f[i][j]=f[i-1][f[i-1][j]];
for(int i=1;i<=Q;++i)
{
for(int j=MD;~j;--j)
{
if(dep[f[j][x]]>dep[z]) ans+=1<<j,x=f[j][x];
if(dep[f[j][y]]>dep[z]) ans+=1<<j,y=f[j][y];
}
if(ans>n) {puts("-1");continue;}
if(x==z||y==z) {printf("%d\n",ans+1);continue;}
if(dfn[x]>dfn[y]) swap(x,y);
printf("%d\n",ans+2-bool(Query(rt[nr[y]],dfn[x],nr[x])-Query(rt[dfn[y]-1],dfn[x],nr[x])));
}
return 0;
}

posted @ 2018-05-17 09:00  FallDream  阅读(514)  评论(0编辑  收藏  举报