T1转圈游戏
题解:快速幂
代码:
#include<iostream> #include<cstring> #include<cstdio> #define LL long long using namespace std; int n,m,k,x; void read(int &x){ char ch=getchar();x=0;int f=1; for(;!isdigit(ch);ch=getchar())if(ch=='-')f=-1; for(;isdigit(ch);ch=getchar())x=x*10+ch-'0'; x=x*f; } LL ksm(int x,int y){ LL ret=1%n; while(y){ if(y&1)ret=ret*x%n; x=x*x%n; y>>=1; } return ret; } int main(){ freopen("circle.in","r",stdin); freopen("circle.out","w",stdout); read(n);read(m);read(k);read(x); cout<<(x%n+m*ksm(10,k)%n)%n<<endl; fclose(stdin);fclose(stdout); return 0; }
T2火柴排队
题解:逆序对
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #define maxn 100009 #define mod 99999997 using namespace std; int ans,n,c[maxn],tree[maxn]; struct F{ int h,id; }a[maxn],b[maxn]; void read(int &x){ char ch=getchar();x=0;int f=1; for(;!isdigit(ch);ch=getchar())if(ch=='-')f=-1; for(;isdigit(ch);ch=getchar())x=x*10+ch-'0'; x=x*f; } bool cmp(F a,F b){ return a.h<b.h; } int lowbit(int x){ return x&(-x); } void add(int x){ while(x<=n){ tree[x]++; x+=lowbit(x); } } int sum(int x){ int ret=0; while(x){ ret+=tree[x]; x-=lowbit(x); } return ret; } int main(){ freopen("match.in","r",stdin); freopen("match.out","w",stdout); read(n); for(int i=1;i<=n;i++)read(a[i].h),a[i].id=i; for(int i=1;i<=n;i++)read(b[i].h),b[i].id=i; sort(a+1,a+n+1,cmp);sort(b+1,b+n+1,cmp); for(int i=1;i<=n;i++)c[a[i].id]=b[i].id; for(int i=1;i<=n;i++){ add(c[i]); ans=(ans%mod+(i-sum(c[i])%mod)%mod); } cout<<ans<<endl; fclose(stdin);fclose(stdout); return 0; }
T3货车运输
题解:最大生成树+kruskal重构树
#include<iostream> #include<cstdio> #include<algorithm> #define maxn 100009 #define maxm 500009 using namespace std; int n,m,tot,sumedge,nn,qx; int head[maxn],dad[maxn],deep[maxn],size[maxn],top[maxn],w[maxn],fa[maxn]; struct E{ int x,y,z; }e[maxm]; struct Edge{ int x,y,nxt; Edge(int x=0,int y=0,int nxt=0): x(x),y(y),nxt(nxt){} }edge[maxn<<1]; void add(int x,int y){ edge[++sumedge]=Edge(x,y,head[x]); head[x]=sumedge; } bool cmp(E a,E b){ return a.z>b.z; } int f(int x){ fa[x]==x?x:fa[x]=f(fa[x]); } void dfs(int x){ size[x]=1;deep[x]=deep[dad[x]]+1; for(int i=head[x];i;i=edge[i].nxt){ int v=edge[i].y; if(v==dad[x])continue; dad[v]=x; dfs(v); size[x]+=size[v]; } } void dfs_(int x){ int s=0; if(!top[x])top[x]=x; for(int i=head[x];i;i=edge[i].nxt){ int v=edge[i].y; if(v!=dad[x]&&size[v]>size[s])s=v; } if(s){ top[s]=top[x]; dfs_(s); } for(int i=head[x];i;i=edge[i].nxt){ int v=edge[i].y; if(v!=dad[x]&&v!=s)dfs_(v); } } int lca(int x,int y){ for(;top[x]!=top[y];){ if(deep[top[x]]>deep[top[y]])swap(x,y); y=dad[top[y]]; } if(deep[x]>deep[y])return w[y]; return w[x]; } int main(){ freopen("truck.in","r",stdin); freopen("truck.out","w",stdout); scanf("%d%d",&n,&m);nn=n; for(int i=1;i<=m;i++)scanf("%d%d%d",&e[i].x,&e[i].y,&e[i].z); sort(e+1,e+m+1,cmp);for(int i=1;i<=n;i++)fa[i]=i; for(int i=1;i<=m;i++){ int fx=f(e[i].x),fy=f(e[i].y); if(fx!=fy){ nn++;w[nn]=e[i].z; add(fx,nn);add(nn,fx); add(fy,nn);add(nn,fy); fa[nn]=nn;fa[fx]=nn;fa[fy]=nn; if(++tot==n-1)break; } } dfs(nn);dfs_(nn); scanf("%d",&qx); for(int i=1;i<=qx;i++){ int x,y; scanf("%d%d",&x,&y); if(f(x)!=f(y))printf("-1 "); else printf("%d ",lca(x,y)); } fclose(stdin);fclose(stdout); return 0; }
树链剖分
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #define inf 100000000 #define maxn 10009 using namespace std; int n,m,q,sumedge,cnt,tot,qx; int head[maxn],dad[maxn],deep[maxn],size[maxn],fe[maxn]; int w[maxn],top[maxn],re[maxn],tpos[maxn],fa[maxn]; struct E{ int x,y,z; }e[maxn*5]; struct Tree{ int l,r,mn; }tr[maxn<<2]; struct Edge{ int x,y,z,nxt; Edge(int x=0,int y=0,int z=0,int nxt=0): x(x),y(y),z(z),nxt(nxt){} }edge[maxn<<1]; void add(int x,int y,int z){ edge[++sumedge]=Edge(x,y,z,head[x]); head[x]=sumedge; } bool cmp(E a,E b){ return a.z<b.z; } int f(int x){ return fa[x]==x?x:fa[x]=f(fa[x]); } void dfs(int x){ size[x]=1;deep[x]=deep[dad[x]]+1; for(int i=head[x];i;i=edge[i].nxt){ int v=edge[i].y; if(v==dad[x])continue; dad[v]=x; dfs(v); size[x]+=size[v]; } } void dfs_(int x,int v){ int s=0,t=0;tpos[x]=++cnt;re[cnt]=x;fe[x]=v; if(!top[x])top[x]=x; for(int i=head[x];i;i=edge[i].nxt){ int v=edge[i].y; if(v!=dad[x]&&size[v]>size[s])s=v,t=edge[i].z; } if(s){ top[s]=top[x]; dfs_(s,t); } for(int i=head[x];i;i=edge[i].nxt){ int v=edge[i].y; if(v!=dad[x]&&v!=s)dfs_(v,edge[i].z); } } int lca(int x,int y){ for(;top[x]!=top[y];){ if(deep[top[x]]>deep[top[y]])swap(x,y); y=dad[top[y]]; } if(deep[x]>deep[y])return y; return x; } void pushup(int rt){ tr[rt].mn=min(tr[rt<<1].mn,tr[rt<<1|1].mn); } void build(int rt,int l,int r){ tr[rt].l=l;tr[rt].r=r; if(l==r){ tr[rt].mn=fe[re[l]]; return ; } int mid=(l+r)>>1; build(rt<<1,l,mid);build(rt<<1|1,mid+1,r); pushup(rt); } int query(int rt,int l,int r,int ql,int qr){ if(l>=ql&&r<=qr){ return tr[rt].mn; } int ans=inf,mid=(l+r)>>1; if(ql<=mid)ans=min(ans,query(rt<<1,l,mid,ql,qr)); if(qr>mid)ans=min(ans,query(rt<<1|1,mid+1,r,ql,qr)); return ans; } int query_mn(int x,int y){ int ret=inf; for(;top[x]!=top[y];){ if(deep[top[x]]>deep[top[y]])swap(x,y); ret=min(ret,query(1,1,n,tpos[top[y]],tpos[y])); y=dad[top[y]]; } if(deep[x]>deep[y])swap(x,y); ret=min(ret,query(1,1,n,tpos[x]+1,tpos[y])); printf("%d ",ret); } int main(){ scanf("%d%d",&n,&m); for(int i=1;i<=m;i++)scanf("%d%d%d",&e[i].x,&e[i].y,&e[i].z); for(int i=1;i<=n;i++)fa[i]=i; sort(e+1,e+m+1,cmp); for(int i=m;i>=1;i--){ int x=e[i].x,y=e[i].y; int fx=f(x),fy=f(y); if(fx!=fy){ fa[fx]=fy;tot++; add(x,y,e[i].z); add(y,x,e[i].z); if(tot==n-1) break; } } for(int i=1;i<=n;i++){ if(size[i]==0){ dfs(i);dfs_(i,0); } } build(1,1,n); scanf("%d",&qx); for(int i=1;i<=qx;i++){ int x,y; scanf("%d%d",&x,&y); if(f(x)!=f(y))printf("-1 "); else query_mn(x,y); } return 0; }