江南程序设计竞赛联盟暑期多校训练·第一场
A. 构造的芙莉莲异或公式:x^y^yx1.aa^b2.ba^b其中aa^b -- ba^b^b 实现将a的值赋给b3.aa^b其中aa^b,ba -- aa^b^a 实现将b的值赋给a如此三步做到a和b位置互换当a[i]!b[i]时,用上述方法调换a[i]和a[j]的位置使a[i]b[i]因题中所述b是1-n的排列,所以经过多次位置调换后,a肯定能满足b的要求#includebits/stdc.h #define int long long using namespace std; const int N1e65; int n,a[N],b[N],now[N];//now[i]记录i在a数组中的下标 vectorpairint,intans; signed main(){ cinn; for(int i1;in;i){ cina[i]; now[a[i]]i; } for(int i1;in;i)cinb[i]; for(int i1;in;i){ if(a[i]b[i])continue; int t1a[i],t2now[b[i]];//存储a[i]的值和b[i]现在的位置 a[i]a[i]^a[now[b[i]]]; ans.push_back({i,now[b[i]]}); a[now[b[i]]]a[now[b[i]]]^a[i]; ans.push_back({now[b[i]],i}); a[i]a[i]^a[now[b[i]]]; ans.push_back({i,now[b[i]]}); now[t1]t2; now[b[i]]i;//实现a[i]与a[now[b[i]]]的位置调换 } coutYesendlans.size()endl; for(int i0;ians.size();i){ coutans[i].first ans[i].secondendl; } }G. 银狼的字符串本题用滑动窗口的思想,窗口从左侧开始,当满足要求后,窗口左端向右收缩;当 不满足要求后,窗口右端向右扩展#include bits/stdc.h using namespace std; #define int long long int n,need[30],now[30],ok,ans1e9; //need[i]记录字母i所需要的字母个数 //now[i]记录字母i已经有的个数 //ok记录满足要求的字母个数 string s; string wordsilverwolf; signed main(){ cinns; for(int i0;iword.size();i){ int xword[i]-a; need[x]; } int l0,r0; while(rs.size()){ int xs[r]-a; now[x]; if(now[x]need[x]){//此字母满足需求,ok ok; } while(ok9){//所有字母都满足需求 ansmin(ans,r-l); xs[l]-a; l;//窗口左端向右移动 now[x]--; if(now[x]need[x])ok--;//移动删去字母后,不再满足silverwolf需求 } r;//窗口右端向右移动 } if(ans1e9)cout-1endl; else coutansendl; }I. 实验报告缝合本题采用哈夫曼树的思想,让结果最小化k叉哈夫曼树,每次合并k个元素,生成1个新元素,即每次消耗k-1个元素故叶子个数应为(k-1)的倍数1,若叶子数量不满足要求,则补0#include bits/stdc.h #define int long long using namespace std; int n,k,T; signed main(){ cinT; while(T--){ int ans0; priority_queueint,vectorint,greaterintbook;//book存储每份报告的页数,小堆顶,满足哈夫曼树优先使用最小元素的思想 cinnk; for(int i0;in;i){ int page; cinpage; book.push(page); } if(k!2){//当k2时,报告数量肯定满足1的倍数1,无需补0,故排除 while(book.size()%(k-1)!1){ book.push(0); } } while(book.size()!1){//合并至最终只剩一份报告 int sum0; for(int i1;ik;i){//将k份报告合并 sumbook.top(); book.pop();//弹出被合并的报告 } anssum;//每次合并消耗代价sum book.push(sum);//合并出来的报告放回队列中 } coutansendl; } }J. 重生之我在崩铁强化获得满分遗器dp[i]记录从0级到i级的期望从i-1级尝试升到i级时,需要点击一次,故从0级到i级的点击次数为dp[i-1]1次从i-1级尝试升到i级时,成功概率为p[i],故从0级到i级的期望次数为(dp[i-1]1)*(1/p[i])dp[i](dp[i-1]1)*(1/p[i])其中p[i]a/b#include bits/stdc.h #define int long long using namespace std; int n,mod1e97,dp[1000005]; int ny(int a){ int ans1,bmod-2; while(b){ if(b%21){ ans(ans*a)%mod; } aa*a%mod; b/2; } return ans; } signed main(){ cinn; for(int i1;in;i){ int a,b; cinab; dp[i](dp[i-1]1)*b%mod*ny(a)%mod; } coutdp[n]; }