AtCoder Regular Contest 111
由于不想被退学忙于学习,好久不打了……
A
感觉不是那么签到……问题可以转化为10^n=am^2+bm+c,求b,然后就转化为普通的快速幂即可
#include<bits/stdc++.h> using namespace std; long long n; int m,a=10,ret=1; int main() { cin>>n>>m; while(n) { if(n%2)ret=1ll*ret*a%(m*m); a=1ll*a*a%(m*m),n>>=1; } printf("%d\n",ret/m); }
B
发现如果把每一张卡片视为一条无向边(ai,bi),答案就是每个连通块中点数和边数的最小值,证明可以任取连通块中的一棵生成树,尝试加边即可证明。
#include<bits/stdc++.h> using namespace std; const int N=4e5+7; int n,ans,f[N],sz[N],e[N]; int find(int x){return x==f[x]?x:f[x]=find(f[x]);} int main() { scanf("%d",&n); for(int i=1;i<=4e5;i++)sz[i]=1,f[i]=i; for(int i=1,x,y;i<=n;i++) { scanf("%d%d",&x,&y); x=find(x),y=find(y); if(x!=y)f[x]=y,sz[y]+=sz[x],e[y]+=e[x]+1; else e[x]++; } for(int i=1;i<=4e5;i++)ans+=min(e[find(i)],sz[find(i)]),e[find(i)]=sz[find(i)]=0; printf("%d\n",ans); }
C
容易发现对每一个目标箱子不在自己手上的人,体重重于目标箱子即可,然后从体重轻的开始交换就行了,但是由于细节WA了一发导致本身不高的名次更加难堪
#include<bits/stdc++.h> using namespace std; const int N=2e5+7; struct node{int x,id;}a[N]; int n,m,b[N],p[N],pid[N],aa[N],ab[N],pos[N]; bool cmp(node a,node b){return a.x<b.x;} int main() { scanf("%d",&n); for(int i=1;i<=n;i++)scanf("%d",&a[i].x),a[i].id=i; for(int i=1;i<=n;i++)scanf("%d",&b[i]); for(int i=1;i<=n;i++)scanf("%d",&p[i]),pid[p[i]]=i; for(int i=1;i<=n;i++)if(i!=p[i]&&a[i].x<=b[p[i]]){puts("-1");return 0;} sort(a+1,a+n+1,cmp); for(int i=1;i<=n;i++) if(p[a[i].id]!=a[i].id) { int now=a[i].id; aa[++m]=now,ab[m]=pid[now]; p[pid[now]]=p[now],pid[p[now]]=pid[now]; } printf("%d\n",m); for(int i=1;i<=m;i++)printf("%d %d\n",aa[i],ab[i]); }
D
石乐志没想出这题……
就是c相同时随便连一连,不同时从大的连到小的就行了
#include <bits/stdc++.h> using namespace std; const int N=1e4+7; int n,m,a[N],b[N],c[N]; bool e[N][N],vis[N]; vector<int>G[N]; void dfs(int u) { vis[u]=1; for(int v:G[u]) if(c[u]>c[v]||c[u]==c[v]&&!e[u][v]&&!e[v][u]) { e[u][v]=1; if(!vis[v])dfs(v); } } int main() { scanf("%d%d",&n,&m); for(int i=1;i<=m;i++) scanf("%d%d",&a[i],&b[i]),G[a[i]].push_back(b[i]),G[b[i]].push_back(a[i]); for(int i=1;i<=n;i++)scanf("%d",&c[i]); for(int i=1;i<=n;i++)if(!vis[i])dfs(i); for(int i=1;i<=m;i++)if(e[a[i]][b[i]])puts("->");else puts("<-"); }
E
数学退化了
记l=A+Bi,r=A+Ci,原题可转化成求使得[(l-1)/D]==[r/D]的i的个数,易得i<=(D-2)/(C-B),令k=(D-2)/(C-B),正难则反,可以求不等于的个数,也就是Σ([(A+Ci)/D]-[(A+Bi-1)/D]),然后要求用O(log(D))的时间求形如Σ[(a+bi)/c]的值,这个可以用类欧几里得去做,可惜我都忘了QAQ
#include<bits/stdc++.h> using namespace std; typedef long long ll; ll f(ll a,ll b,ll c,ll n) { if(!a)return(n+1)*(b/c); if(a>=c||b>=c)return(f(a%c,b%c,c,n)+(a/c)*n*(n+1)/2+b/c*(n+1)); ll m=(a*n+b)/c; return n*m-f(c,c-b-1,a,m-1); } int main() { int T;scanf("%d",&T); while(T--) { ll a,b,c,d,k;scanf("%lld%lld%lld%lld",&a,&b,&c,&d); k=(d-2)/(c-b); printf("%lld\n",k-f(c,a,d,k)+a/d+f(b,a-1,d,k)-(a-1)/d); } }
新号打的
rank371 performance=1978 rating=778