当前位置: 首页 > news >正文

wordpress获取小工具网站排名优化怎么样

wordpress获取小工具,网站排名优化怎么样,湖北网站备案需要多久,南阳高质量建设大城市网站前言 沟槽的D卡了我一个多小时&#xff0c;快结束看了眼E发现E这么简单&#xff0c;结果就是比赛结束了才过了E&#xff0c;之后发现群友的D的思路是真的妙……还是太菜了T^T 一、A. Lever #include <bits/stdc.h> using namespace std;typedef long long ll; typedef…

前言

沟槽的D卡了我一个多小时,快结束看了眼E发现E这么简单,结果就是比赛结束了才过了E,之后发现群友的D的思路是真的妙……还是太菜了T^T

一、A. Lever

#include <bits/stdc++.h>
using namespace std;typedef long long ll;
typedef pair<int,int> pii;
typedef pair<ll,ll>pll;void solve()
{int n;cin>>n;vector<int>a(n+1);for(int i=1;i<=n;i++){cin>>a[i];}vector<int>b(n+1);for(int i=1;i<=n;i++){cin>>b[i];}int ans=0;while(true){bool flag=true;for(int i=1;i<=n;i++){if(a[i]>b[i]){a[i]--;flag=false;break;}}for(int i=1;i<=n;i++){if(a[i]<b[i]){a[i]++;break;}}ans++;if(flag){break;}}cout<<ans<<endl;
}int main()
{ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);int t=1;cin>>t;while(t--){solve();    }return 0;
}

这个题可以看到数据量很小,那就直接模拟做就可以了。那就是每次迭代都先过一遍a数组,如果有一个比b数组大那就减小,然后直接break。之后再过一遍a数组,如果比b数组小就增加,然后break。最后看如果第一次操作没发生过那就直接退出输出答案即可。

二、B. Alternating Series

#include <bits/stdc++.h>
using namespace std;typedef long long ll;
typedef pair<int,int> pii;
typedef pair<ll,ll>pll;void solve()
{int n;cin>>n;if(n%2==0){for(int i=1;i<n;i++){if(i%2==1){cout<<-1<<" ";}else{cout<<3<<" ";}}cout<<2<<endl;}else{for(int i=1;i<=n;i++){if(i%2==1){cout<<-1<<" ";}else{cout<<3<<" ";}}cout<<endl;}
}int main()
{ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);int t=1;cin>>t;while(t--){solve();    }return 0;
}

这就是一个简单的构造题。

既然要求绝对值的字典序最小,那么贪心一下肯定是由-1开始,正负正负这样交替。又因为必须满足子数组的累加和是正数,所以对于中间的每个正数,累加和最小的情况肯定是选左右的负数组成的长度为三的子数组。又因为为了保证字典序最小,所以负数肯定都要选-1,那么只要中间的正数是3就一定能保证累加和是正数。而如果最后以正数结尾,那么因为右侧没有-1了,所以填2就能保证累加和是正数。

三、C. Make it Equal

#include <bits/stdc++.h>
using namespace std;typedef long long ll;
typedef pair<int,int> pii;
typedef pair<ll,ll>pll;void solve()
{ll n,k;cin>>n>>k;vector<ll>s(n+1);for(int i=1,x;i<=n;i++){cin>>x;s[i]=x%k;}multiset<ll>t;for(int i=1,x;i<=n;i++){cin>>x;t.insert(x%k);}for(int i=1;i<=n;i++){if(t.find(s[i])!=t.end()){t.erase(t.find(s[i]));}else if(t.find(k-s[i])!=t.end()){t.erase(t.find(k-s[i]));}else{cout<<"NO"<<endl;return ;}}cout<<"YES"<<endl;
}int main()
{ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);int t=1;cin>>t;while(t--){solve();    }return 0;
}

这题真的坑,上来看了半天没想明白,后来纯靠猜还真给猜过了。

观察发现,因为可以无限次加减k,所以其实这些数的原始数根本不重要,是需要考虑模k后的余数即可,就是把所有数都一直减k减到再减就小于0为止。这样操作后,对于可以通过反复加k相等的数,这两个数模k的余数肯定是一样的。之后,只需要过一遍s数组,每次考察这个余数和进行一次减k操作后的数在t中是否存在即可,如果两个都不存在就肯定没法凑成。

四、D. Arboris Contractio

还得加训树形结构……

#include <bits/stdc++.h>
using namespace std;typedef long long ll;
typedef pair<int,int> pii;
typedef pair<ll,ll>pll;const int MAXN=2e5+5;void solve()
{int n;cin>>n;vector<vector<int>>g(n+1);for(int i=0,u,v;i<n-1;i++){cin>>u>>v;g[u].push_back(v);g[v].push_back(u);}//叶节点的总个数int sum=0;//连接到同一个节点的叶节点数的最大值int mx=0;for(int i=1;i<=n;i++){int tmp=0;//自己就是叶节点if(g[i].size()==1){sum++;tmp++;}for(int v:g[i]){//孩子是叶节点if(g[v].size()==1){tmp++;}}mx=max(mx,tmp);}//选择有最多叶节点的节点为中心点//操作数就是全部叶节点的个数sum减去最多叶节点的个数mxcout<<sum-mx<<endl;
}int main()
{ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);int t=1;cin>>t;while(t--){solve();    }return 0;
}

群友的这个思路太妙了……

首先贪心一下,上来选择叶节点最多的节点肯定不会亏。因为整个过程就是每次把最长链上的节点都连到中心节点,那么每次剩下没连的就是叶节点。所以就是先考察每个节点,统计叶节点的总数和叶节点最多的节点的叶节点个数,并选择这个节点为中心节点。那么之后一次重连肯定只能解决一个叶节点,所以操作数就是叶节点的总数减去最多叶节点个数。

注意力惊人了属于是,赛时根本没往叶节点这方面考虑……

五、E. Adjacent XOR

赛时最后五分钟搓的,一塌糊涂但能过()

#include <bits/stdc++.h>
using namespace std;typedef long long ll;
typedef pair<int,int> pii;
typedef pair<ll,ll>pll;void solve()
{int n;cin>>n;vector<ll>a(n+1);for(int i=1;i<=n;i++){cin>>a[i];}vector<ll>b(n+1);for(int i=1;i<=n;i++){cin>>b[i];}if(a[n]!=b[n]){cout<<"NO"<<endl;return ;}vector<ll>dp(n+1);dp[n]=a[n];for(int i=n-1;i>=1;i--){if(a[i]!=b[i]){if((a[i]^dp[i+1])==b[i]){dp[i]=a[i]^dp[i+1];}else if((a[i]^a[i+1])==b[i]){dp[i]=a[i]^a[i+1];}else{cout<<"NO"<<endl;return ;}}else{dp[i]=a[i];}}cout<<"YES"<<endl;
}int main()
{ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);int t=1;cin>>t;while(t--){solve();    }return 0;
}

首先这个题可以发现修改操作只依赖右侧的值,那么对于最右侧的数,根本没法进行修改。所以就先判断最右侧的两个数,如果不同那就根本不可能凑成。因为每个操作只依赖右侧的值,那么可以考虑从后往前遍历。之后可以考虑dp一下,用dp数组存最终i位置的数。那么如果两数本来就相等,那根本就不用改,直接设置eor数组为原始数。如果不同的话,就需要修改了。修改的策略有两种,要么异或右侧原始的数,要么异或右侧修改后的数。那么就是如果跟右侧最终的数,即dp值异或后相等,那就设置当前位置的dp值为异或右侧dp值的结果。如果不行,那么如果跟右侧原始数异或能相等,就设置dp值为异或右侧原始值的结果。如果都不相等,那就根本不可能完成。

六、F. Unjust Binary Life

这b题是真的难……

#include <bits/stdc++.h>
using namespace std;typedef long long ll;
typedef pair<int,int> pii;
typedef pair<ll,ll>pll;//大于等于x的最左位置
int bs(ll x,int n,vector<array<ll,3>>&cnts)
{int l=0;int r=n-1;int m;int ans=n;while(l<=r){m=(l+r)/2;if(cnts[m][0]>=x){ans=m;r=m-1;}else{l=m+1;}}return ans;
}void solve()
{int n;cin>>n;string a,b;cin>>a>>b;//如果(i,j)->(i+1,j),那么有Ai^Bj=0,A(i+1)^Bj=0//所以可以合并得到Ai^A(i+1)=0,即Ai==A(i+1)//而如果(i,j)->(i,j+1),那么有Ai^Bj=0,Ai^B(j+1)=0//所以可以得到Bj^B(j+1)=0,即Bj==B(j+1)//又因为Ai^Bj=0,即Ai==Bj//所以如果能从(1,1)->(i,j),必须有A1~Ai和B1~Bj的所有数全相等//所以最小操作次数就是min(ones,zeros)//所以可以考虑先预处理a串中从头到i的0的个数zeros和1的个数ones//再根据zeros-ones从小到大排序,生成预处理数组help//之后遍历b串,每次统计b串的zeros和ones//去help里二分找大于等于b串ones-zeros的最左位置l//此时对答案的贡献就是a串0~l上每个位置0的个数的累加和加上b串目前0的个数乘l//再加上a串后续每个位置1的个数的累加和加上b串目前1的个数乘后续的长度//举个例子,假如help={-1,-1,0,0}//当来到b串的2位置,ones=2,zeros=1,ones-zeros=1//说明b串到这个位置1的个数比0的个数多1//所以说明a串中有四个位置补不上0比1少的个数,那么操作数就是0的个数//那么对答案的贡献就是a串中0的个数加上b串目前0的个数乘以4//再加上右侧操作数为1的个数的答案,即a串中后续1的个数加上b串目前1的个数乘以4-4=0vector<array<ll,3>>cnts(n);ll ones=0;ll zeros=0;for(int i=0;i<n;i++){if(a[i]=='0'){zeros++;}else{ones++;}cnts[i]={zeros-ones,zeros,ones};}sort(cnts.begin(),cnts.end(),[&](const array<ll,3>&x,const array<ll,3>&y){return x[0]<y[0];});vector<ll>pre0(n);vector<ll>pre1(n);pre0[0]=cnts[0][1];pre1[0]=cnts[0][2];for(int i=1;i<n;i++){pre0[i]=pre0[i-1]+cnts[i][1];pre1[i]=pre1[i-1]+cnts[i][2];}zeros=0;ones=0;ll ans=0;for(int i=0;i<n;i++){if(b[i]=='0'){zeros++;}else{ones++;}int pos=bs(ones-zeros,n,cnts);if(pos==0){ans+=pre1[n-1]+ones*n;}else{ans+=pre0[pos-1]+zeros*pos+pre1[n-1]-pre1[pos-1]+ones*(n-pos);}}cout<<ans<<endl;
}int main()
{ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);int t=1;cin>>t;while(t--){solve();    }return 0;
}

这个题上来的这个思路就想不到。根据定义,假如能从(i,j)走到(i,j+1),那么因为Ai^Bj等于0,又因为Ai^B(j+1)等于0,所以把这两个式子再异或起来可以得到Bj^B(j+1)等于0。同理可以得到Ai^A(i+1)等于0,所以如果能从(1,1)走到(i,j),那么必须有从A1到Ai,从B1到Bj,所有的数都完全一样。那么要保证能走到的最小操作数就是这些数字里,0的个数和1的个数的最小值。所以,所有操作的代价就是对于所有的二元对(i,j)的最小操作数。

之后就需要考虑如何将复杂度降下来了。考虑先遍历一遍a串,每次统计从头到当前i位置,0的个数zeros和1的个数ones,以及zeros减ones的个数。之后,根据zeros减ones从小到大排序,然后分别求整个数组里zeros和ones的前缀和。之后,遍历b串,同样统计从头到当前位置的zeros和ones。

之后是重点,举个例子,假如b串从头到当前位置的zeros为2,ones为4,那么ones减zeros就是2,表明1的个数比0的个数多2个。之后,去之前a串统计出的数组里,二分查找大于等于2的最左位置pos。那么对于这个位置pos,左侧部分都是zeros减ones小于等于2的,即0的个数和1的个数弥补不了b串当前的差距,所以此时合起来0的个数和1的个数的最小值就是0的个数。同理,这个位置pos的右侧位置都是zeros减ones大于2的,即合起来后1最小值是1的个数。所以,0的个数和1的个数可以直接从前缀和数组里查,再加上b串当前的zeros和ones乘以对应个数即可。

真的离谱这个思路……

七、G. Wafu!

这个G感觉也不过如此嘛。

#include <bits/stdc++.h>
using namespace std;typedef long long ll;
typedef pair<int,int> pii;
typedef pair<ll,ll>pll;const int MOD=1e9+7;//找小于等于的最右位置
int bs(ll x,int n,vector<ll>&cnts)
{int l=1;int r=n;int m;int ans=0;while(l<=r){m=(l+r)/2;if(cnts[m]<=x){ans=m;l=m+1;}else{r=m-1;}}return ans;
}void solve()
{ll n,k;cin>>n>>k;vector<ll>s(n+1);for(int i=1;i<=n;i++){cin>>s[i];}sort(s.begin()+1,s.end());//cnts[i]:1~i乘完的次数vector<ll>cnts(32);//mult[i]:1~i乘完vector<ll>mult(32);cnts[0]=0;mult[0]=1;for(int i=1;i<32;i++){cnts[i]=cnts[i-1]*2+1;mult[i]=((mult[i-1]*mult[i-1])%MOD*i)%MOD;}ll ans=1;int i=1;while(k>0){if(i<=n&&s[i]-1<32&&k>=1+cnts[s[i]-1])//能乘数组里的并把新增的乘完{ans=(ans*s[i])%MOD;ans=(ans*mult[s[i]-1])%MOD;k-=1+cnts[s[i]-1];i++;}else{//还能乘数组里的if(i<=n){ans=(ans*s[i])%MOD;k--;i++;}//只能乘新增的int pos=31;while(k>0){//二分找最多乘到的位置pos=bs(k,pos,cnts);ans=(ans*mult[pos])%MOD;k-=cnts[pos];//还能再乘一次if(k>0){ans=(ans*(pos+1))%MOD;k--;}}}}cout<<ans<<endl;
}int main()
{ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);int t=1;cin>>t;while(t--){solve();    }return 0;
}

首先,因为每次从集合里删除一个数后,都要把从1到这个数中间的所有数都加入集合。又因为每次都选集合中最小的数,所以每次肯定会优先处理新加入的数。那么就可以考虑用dp的思想,先预处理一个cnts数组,cnts[i]表示集合的前i个数正好为1~i,把这i个数删完需要的次数。再预处理一个mult数组,其中mult[i]还是表示集合的前i个数正好为1~i,把这i个数删完答案一共要乘的数。再观察可以发现,在删除的过程中,在删第i个数i之前,肯定要把1~i-1删完,之后才能删i。接着因为又加入了1~i-1,所以还得再删一遍1~i-1,那么就可以得到如上面写的转移公式。通过观察cnts[i]的数可以发现,cnts[i]其实就等于2^i-1。又因为k小于等于10^9,没超过int的范围,所以cnts和mult都只需要开32长度即可。又因为每次在删完集合中的数x后,都要处理1~x-1的部分,那么只有当这个x-1小于32时,才有可能把新增的全删完。

之后,在对数组从小到大排序后,只要k大于0,那么如果数组里还有数,即原本的集合没被删完,且集合中的数-1小于32,即能把新增的全删完,且k的次数比删完一轮的次数还大,那就先删集合内的数,再把1~x-1全删完。否则,说明k不够全删完的了,那如果此时集合里还有数,那就先删集合里的。之后,因为新增的数删不完,只要k还大于0,那么每次能完整删完的1~i就可以在cnts里二分查找小于等于k的最右位置,然后把1~i这一部分全删了。如果还能再删一次,那么就再把数字i+1给删了,去后续看能否接着删了。

总结

一步一步来,天道酬勤,加油!!

END

http://www.dtcms.com/a/552404.html

相关文章:

  • 免费自助建站哪个平台好什么类型的网站容易被百度抓取
  • 网站空间ftp下载慢快速开发平台有哪些
  • 怎么做网站首页关键词电商代运营公司排行榜
  • 徐州市网站开发设计灵感网站整理
  • wordpress在页面中调用文章杭州新站整站seo
  • 手表网站登录页背景图优质的菏泽网站建设
  • 电商网站开发多少钱免费网站推广产品
  • 如何制作自己的网站国内做企业英文网站用什么cms
  • 网络公司网站建设报价软件设计专业介绍
  • 门户网站建设目的关注江苏建设厅网站
  • php建设网站所用开发软件凡科app制作
  • 公司注销 网站备案申请表seo建站教学
  • 专业的网站建设托管公司简介网页模板
  • 网站推广渠道类型外网wordpress好慢
  • 做国外网站的公证要多少钱wordpress php5.3.5访问慢
  • 江苏建设通网站做高端品牌网站
  • 深圳市招聘网站三合一网站建设官网
  • 苏州网站建设空间网页开发语言有哪几种
  • 四川省建设厅职称查询网站烟台网站建设外贸
  • 云南固恒建设集团有限公司网站女生读电子商务好就业吗
  • 小型公司建网站沈阳大东区做网站公司
  • 网站建设 中企动力中山wordpress模板下载云落
  • 烟台企业做网站甘肃网站建设哪家好
  • 苏州 网站 建设 公司事业单位可以建设网站吗
  • wordpress博客网站长沙网站建设建
  • 旅游网站开发公司济南网站建设 刘彬彬
  • 响应式网站psd尺寸青岛公司建站
  • 中交上航建设网站英文外链seo兼职
  • 成都大型网站设计公司做网站不搭建本地环境
  • 酒店网站建设特色wordpress建单页面论坛