题意:给出一个n,每次减去一个t(t<n&&t不是n的除数),问最终的最小结果
解法:n与n-1互质,对2进行特判即可


#include<bits/stdc++.h> using namespace std; int main(){ int n;scanf("%d",&n); if(n>2) printf("1\n"); else printf("%d\n",n); return 0; }
题意:每个人有一顶帽子,有一定的颜色,每个人给出ai,代表帽子颜色与自己不同的人数,求构造n个人帽子的颜色
解法:每个人可以知道有多少人的帽子颜色跟自己相同,排序之后一块一块操作就好,不满足就输出-1即可


#include<bits/stdc++.h> using namespace std; const int N=1e5+10; int b[N]; struct node{int v,id;}a[N]; bool cmp(node a,node b){return a.v<b.v;} int main(){ int n;scanf("%d",&n); for(int i=1;i<=n;i++)scanf("%d",&a[i].v),a[i].id=i; sort(a+1,a+n+1,cmp);int f=1,pre=-1; int tmp=0; for(int i=1;i<=n;){ int num=n-a[i].v; if(a[i+num-1].v==a[i].v){ tmp++; for(int j=i;j<i+num;j++) b[a[j].id]=tmp; i+=num; } else {f=0;break;} } if(!f) printf("Impossible\n"); else{ printf("Possible\n"); for(int i=1;i<=n;i++) if(i==1) printf("%d",b[i]);else printf(" %d",b[i]); printf("\n"); } return 0; }
题意:n个连续的brick,m中颜色,求有k个brick与自己左边颜色不同的方案数
解法:
1.可以发现是将这n个bricks分成k+1份,相邻颜色不同,即可得出答案C(n-1,k)*m*(m-1)^k +特判;
2.dp dp[i][j]=dp[i-1][j]+dp[i-1][j-1]*(m-1)


#include<bits/stdc++.h> using namespace std; typedef long long ll; const int mod=998244353; ll pow_(ll a,ll b){ ll res=1,tmp=a; while(b){ if(b&1) (res*=tmp)%=mod; b/=2; (tmp*=tmp)%=mod; } return res; } int main(){ ll n,m,k;scanf("%lld%lld%lld",&n,&m,&k); if(m==1) { if(k==0) {printf("1\n");return 0;} else {printf("0\n");return 0;} } ll t1=1,t2=1,t3=1,t4=1,t5=1; for(ll i=1;i<=n-1;i++) t1=t1*i%mod; for(ll i=1;i<=k;i++) t2=t2*i%mod; for(ll i=1;i<=n-1-k;i++) t3=t3*i%mod; ll ans=t1; (ans*=pow_(t2,mod-2))%=mod; (ans*=pow_(t3,mod-2))%=mod; (ans*=m)%=mod; (ans*=pow_(m-1,k))%=mod; printf("%lld\n",ans); return 0; }
题意:给定一个图,给出k个特殊点,定义路径的长度=max(边权),定义点之间的距离=min(路径),对于每个特殊点,求到其他特殊点的最大距离
解法:因点之间的距离是min(路径),即最大值最小,即让这k个点相互连通,且最大的边最小,即构造这k个点的额最小生成树;因无法直接构造这
k个点的最小生成树,所以考虑在构造n个点的最小生成树的同时,构造这k个点的联通,当这k个点恰好联通的时候,即可输出答案;
赛场上:没想到简单的写法,就这届构造了最小生成树的图,然后考虑每个点的子树是否有特殊点,这样判断是否向下搜索,寻找最大边


#include<bits/stdc++.h> using namespace std; const int N=1e5+10; int n,m,k; struct node{int f,t,c;}b[N]; bool cmp(node a,node b){return a.c<b.c;}; int a[N],fa[N]; typedef pair<int,int> pii; vector<pii>g[N];int x; int find(int x){ if(fa[x]==x) return x;else return fa[x]=find(fa[x]); } void unite(int x,int y){x=find(x),y=find(y);fa[x]=y;} int num[N]; void dfs(int x,int fa){ if(a[x]) num[x]=1; for(auto it:g[x]){ int y=it.first,c=it.second; if(y==fa) continue; dfs(y,x); num[x]+=num[y]; } } int max_=0; void dfs2(int x,int fa){ if(num[x]==0) return; for(auto it:g[x]){ int y=it.first,c=it.second; if(y==fa) continue; if(num[y]!=0) max_=max(max_,c),dfs2(y,x); } } int main(){ scanf("%d%d%d",&n,&m,&k); for(int i=1;i<=n;i++) fa[i]=i;int s=-1; for(int i=1;i<=k;i++) scanf("%d",&x),s=x,a[x]=1; for(int i=1;i<=m;i++) scanf("%d%d%d",&b[i].f,&b[i].t,&b[i].c); sort(b+1,b+m+1,cmp);int num_=0; for(int i=1;i<=m;i++){ int x=b[i].f,y=b[i].t; if(find(x)!=find(y)) { unite(x,y);num_++; g[x].push_back({y,b[i].c});g[y].push_back({x,b[i].c}); } if(num_==n-1) break; } //for(int i=1;i<=n;i++) cout<<g[i].size()<<endl; dfs(s,-1);dfs2(s,-1); //for(int i=1;i<=n;i++) cout<<i<<" "<<num[i]<<endl; for(int i=1;i<=k;i++) if(i==1) printf("%d",max_);else printf(" %d",max_); printf("\n"); return 0; }


#include<bits/stdc++.h> using namespace std; const int N=1e5+10; int n,m,k; struct node{int f,t,c;}b[N]; bool cmp(node a,node b){return a.c<b.c;}; int a[N],fa[N]; int x,num[N]; int find(int x){ if(fa[x]==x) return x;else return fa[x]=find(fa[x]); } void unite(int x,int y){x=find(x),y=find(y);fa[y]=x;} int main(){ scanf("%d%d%d",&n,&m,&k); for(int i=1;i<=n;i++) fa[i]=i; for(int i=1;i<=k;i++) scanf("%d",&x),num[x]=1; for(int i=1;i<=m;i++) scanf("%d%d%d",&b[i].f,&b[i].t,&b[i].c); sort(b+1,b+m+1,cmp);int ans_=-1; for(int i=1;i<=m;i++){ int x=b[i].f,y=b[i].t;int xx=find(x),yy=find(y); if(xx!=yy) { fa[yy]=xx;num[xx]+=num[yy]; if(num[xx]==k) {ans_=b[i].c;break;}; } } for(int i=1;i<=k;i++) if(i==1) printf("%d",ans_);else printf(" %d",ans_); printf("\n"); return 0; }
题意:给定一个n,偶数位置的数已知,求构造数列使得每个前缀和均为完全平方数
解法:因为前缀和一定是单调递增的,所以直接遍历k,k*k代表当前的前缀和,贪心找最小的满足条件的k即可;
(说实话。。。标解实在是没看懂,我也没仔细想我这样写为什么是对的,等到和F一块更新吧)


#include<bits/stdc++.h> using namespace std; const int N=2e5+10; typedef long long ll; ll a[N]; bool is_(ll a){ll t=sqrt(a);return t*t==a;} int main(){ int n;scanf("%d",&n); for(int i=2;i<=n;i+=2) scanf("%lld",&a[i]); ll k=0;int i; for(i=1;i<=n;i+=2){ ll pre=k*k;k++; while(!is_(k*k+a[i+1])) {k++;if(k>2e6) {printf("No\n"); return 0;}} a[i]=k*k-pre; k=sqrt(k*k+a[i+1]); } printf("Yes\n"); for(int i=1;i<=n;i++) if(i==1) printf("%lld",a[i]);else printf(" %lld",a[i]); printf("\n"); return 0; }