1635A - Min Or Sum

回忆性题意:改变两个数,但 或 不能变,求整个数组最小和。

挺好想的,只要抓住或运算有一位就够了,并且答案的构造非常可行,就可以解决了。

答案证明给出了一个式子a1∣a2∣...∣an≤a1+a2+...+ana_1|a_2|...|a_n\leq a_1+a_2+...+a_na1​∣a2​∣...∣an​≤a1​+a2​+...+an​挺对的。

1635B - Avoid Local Maximums

回忆性题意:通过最少次数调整,使得local maximum不复存在,比两边都大即是L.M.

我是直接上了就在想如果我是人会怎么做,简单发现,单有一个local maximum时,左右至少变一个;一个operation最多减少两个local max。然后结合样例不断改进自己的算法,就可以了。CF的样例是挺强的。

答案证明是把local max数全部先找出来,分组,每组必须要⌈每组个数2⌉\lceil \frac{每组个数}{2} \rceil⌈2每组个数​⌉次操作。很对,这很数学。

1635C - Differential Sorting(构造)

回忆性题意:ax=ay-az,x<y<z,能否使a单调不减。

分类讨论,很好想的。贪心的去构造就完了。如果但是我留意到是not-decreasing,那构造一个除最后一个外,全部相同的就完事了。

比赛时,我想的是倒数第一个和倒数第二个是变不了的,倒数第三个只有一中改变方法,所以采取了从后往前推的方式,进一步想到了上面的方法。

很喜欢答案的证明,很数学,在an<0a_n<0an​<0时,必有ai<0a_i<0ai​<0通过反证法,结合ax=ay−aza_x=a_y-a_zax​=ay​−az​可以推得矛盾ax>aya_x>a_yax​>ay​,妙。其实我也想到了,不过没有它这么数学化。

1635D - Infinite Set(DP)

乍一看我还以为是一个容斥问题,想放弃。没想到居然会是一个DP。

答案的思路很好,复杂问题,我们先从简单问题开始考虑:n=1,a1=1,p任意,能做吗?

最关键也是最巧妙的地方来了,我们把数分为几段,每一段为[2i−1,2i),i∈N∗[2^{i-1},2^{i}),i\in \N^*[2i−1,2i),i∈N∗。不妨定义f(x)f(x)f(x)表示的就是这个东西。那么我们能发现f(2x+1)=f(x)+1,f(4x)=f(x)+2f(2x+1)=f(x)+1,f(4x)=f(x)+2f(2x+1)=f(x)+1,f(4x)=f(x)+2。

这下,可以写出DP方程了:dp[i]=dp[i−1]+dp[i−2]dp[i]=dp[i-1]+dp[i-2]dp[i]=dp[i−1]+dp[i−2]。初始化dp[1]=1。答案为∑1pdp[i]\sum_{1}^{p}dp[i]∑1p​dp[i]。

如果还原到原问题,那就是增加一个删去重复数的操作。排个序,小到大,奇数减1除2,偶数除4,最多log⁡x\log xlogx的次数可以搞定一个数。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int MOD=1e9+7;
const int N=2e5+10;int n,p;
int a[N];
ll f[N],g[N];
map<int,bool> b;bool check(int aa)
{while(aa>1){if(aa&1) aa=(aa-1)/2;else if(aa%4==0) aa=aa/4;else break;if(b[aa]) return false;}return true;
}int main()
{ios::sync_with_stdio(false);cin.tie(0);cin >> n >> p;for(int i=1;i<=n;i++) cin >> a[i];sort(a+1,a+n+1);for(int i=1;i<=n;i++){if(a[i]==a[i-1]) continue;if(check(a[i])) b[a[i]]=true,g[__lg(a[i])+1]++;}ll ans=g[1];f[1]=g[1];for(int i=2;i<=p;i++) f[i]=(f[i-1]+f[i-2]+g[i])%MOD,ans=(ans+f[i])%MOD;
//  for(int i=0;i<=p;i++) cout << f[i] << " " ;cout << ans << endl;return 0;
}

1635E - Cars(二分图染色)(拓补排序-巧) \ (差分约束)

题意:一种方案,让该相遇车的相遇,不的不。 可否?

挺有意思,想想能够到的题。先确定了不能同方向之后,发现很像二分图,因为只要出现了这两人的关系,他们就一定是反方向行驶,只是起点的左右问题决定是相遇还是不遇。进而,可以二分染色初步判定是否有界。(我年少无知以为新的就可以直接假定是L,殊不知,这个新可能只是没有更新到罢了。还得正正经经建个图、跑一下二分图染色。)

染完后,求一种起点的方案。看到不等式让我想到的是差分约束,建图判负环就OK,答案就是d[x]。差分约束记得要连一条(a0,ai,0)(a_0,a_i,0)(a0​,ai​,0)的边,即ai≤a0+0a_i\leq a_0+0ai​≤a0​+0,再假定a0=0a_0=0a0​=0,对应到最短路就是d0=0d_0=0d0​=0。

我还犯了一个错,ai<aja_i< a_jai​<aj​用差分约束的话来说应该是ai≤aj−1a_i \leq a_j -1ai​≤aj​−1。

不过这个O(nm)O(nm)O(nm)的时间复杂度最终TLE了。

答案说的好,不要大材小用差分约束,留意到每条边边权都是-1,可以直接用拓补排序。可以做到O(n)O(n)O(n)判负环,顺便还能把题给做了,何乐而不为呢。根据题目的特性来做题!!!

不加修饰的AC+TLE代码,将就将就把~

#include<bits/stdc++.h>
using namespace std;
const int INF=999999999;
const int N=2e5+10;int n,m,S;
int v[N];int du[N];struct node{int d,id;}d[N];
bool cmp1(node d1,node d2){return d1.d>d2.d;}
bool cmp2(node d1,node d2){return d1.id<d2.id;}struct E{int y,c,next;}e[2*N];int len=0,last[N];
void ins(int x,int y,int c)
{du[y]++;e[++len]=(E){y,c,last[x]};last[x]=len;
}bool check(int x)
{for(int k=last[x];k;k=e[k].next){int y=e[k].y;if(!v[y]){v[y]=3-v[x];if(!check(y)) return false;}if(v[y]+v[x]!=3) return false;}return true;
}struct Spfa
{queue<int> q;bool in[N];int cnt[N];bool SPFA(){for(int i=1;i<=n;i++) d[i]=(node){INF,i};d[S].d=0;q.push(S);while(!q.empty()){int x=q.front();q.pop();in[x]=false;for(int k=last[x];k;k=e[k].next){int y=e[k].y;if(d[y].d>d[x].d+e[k].c){d[y].d=d[x].d+e[k].c;cnt[y]++;if(cnt[y]>n) return false;//debug cnt[y]==n acutally has n+1 vetexif(!in[y]) q.push(y),in[y]=true;}}}return true;}
}sol1;struct TOPS
{queue<int> q;bool TopSort(){for(int i=1;i<=n;i++) d[i].id=i;int cnt=-1;q.push(S);while(!q.empty()){int x=q.front();q.pop();for(int k=last[x];k;k=e[k].next){int y=e[k].y;du[y]--;if(du[y]==0) d[y].d=d[x].d+1,q.push(y);}cnt++;}return cnt==n;}
}sol2;int opt[N],a[N],b[N];
int main()
{ios::sync_with_stdio(false);cin.tie(0);cin>>n>>m;for(int i=1;i<=m;i++){cin>>opt[i]>>a[i]>>b[i];ins(a[i],b[i],0);ins(b[i],a[i],0);}for(int i=1;i<=n;i++) if(!v[i]){v[i]=1;if(!check(i)) goto fail;}S=n+1;len=0;memset(last,0,sizeof(last));memset(du,0,sizeof(du));for(int i=1;i<=m;i++){int x=a[i],y=b[i];if(opt[i]==1) ins( v[x]>v[y]?x:y , v[x]<v[y]?x:y , -1);//dy(v[x]=1)<=dx(v[x]=2)-1 else ins( v[x]<v[y]?x:y , v[x]>v[y]?x:y , -1);//dy(v[x]=2)<=dx(v[x]=1)-1 }for(int i=1;i<=n;i++) ins(S,i,0);
//  if(!sol1.SPFA()) goto fail;if(!sol2.TopSort()) goto fail;sort(d+1,d+n+1,cmp1);for(int i=1;i<=n;i++) d[i].d=i;sort(d+1,d+n+1,cmp2);cout<<"YES"<<endl;for(int i=1;i<=n;i++) cout<< (v[i]==1?"L ":"R ") << d[i].d <<endl;return 0;fail:cout<<"NO"<<endl;return 0;
}

1635F - Closest Pair(性质分析)(栈)(树状数组)

题意:区间内取两数,使得∣xi−xj∣∗(wi+wj)|x_i-x_j|*(w_i+w_j)∣xi​−xj​∣∗(wi​+wj​)最小。

我以后也要用cin,cout了,很不错的样子,主要是打起来比scanf方便很多,少了很多引号和地址符的烦恼。第一次这么大规模用vector,可惜DEV-C++不争气,版本太落后了,很多高级语句都只能替换掉了。找个时间配一个新的编译器!

是我太弱了,看了好几天终于看懂了F题的tutorial。下面还原一下tutorial的精彩证明:

Lemma:定义L[i]L[i]L[i]为最大的jjj,满足x[j]<x[i]x[j]<x[i]x[j]<x[i],并且w[j]≤w[i]w[j]\leq w[i]w[j]≤w[i];R[i]R[i]R[i]为最小的jjj满足x[i]<x[j]x[i]<x[j]x[i]<x[j],并且w[j]≤w[i]w[j]\leq w[i]w[j]≤w[i]。那么,所有求得的区间一定在(L[i],i)(L[i],i)(L[i],i),和(R[i],i)(R[i],i)(R[i],i)之间。

Proof:对于一对数(a,b)是区间内最优方案,

  1. 如果w[a]<=w[b], 那么一定会有L[b]=a(成立了吧);否则(如果L[b]敢不等于a),那么(a,L[b])将会是比(a,b),更优的选择方案(矛盾了,所以L[b]是不敢不等于a的)。
  2. 如果w[a]>w[b],那么一定会有R[a]=b(成立了吧);否则,(R[a],b)是更优的方案。

证明的后半段是反证法,来说明前面是一定成立的。

一个字:绝!

这个定理中的L[i]L[i]L[i]和R[i]R[i]R[i]是很好用一个栈去把它求出来的。有了这个定理后,我们需要处理的内容就大大减少了。

tutorial给出了一种题意转换,把选择的两个点连一条边,并附上权值。现在题目变成了,给出2n2n2n条带权线段,问位于区间[l,r][l,r][l,r]内线段的最大权值。用扫描线+统计后缀和的一个工具(如BIT树)就可以了。

时间复杂度O((n+q)log⁡n)O((n+q)\log n)O((n+q)logn)

#include<bits/stdc++.h>
#define mp make_pair
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
const int N = 300005;
const ll INF=1ll<<62;int n,q;
vector<pii> queries[N];
vector<int> useful[N];ll bit[N];
void modify(int x,ll val)
{for(;x;x-=x&-x) bit[x]=min(bit[x],val);
}
ll query(int x) //debug int query()
{ll re=INF;for(;x<=n;x+=x&-x) re=min(re,bit[x]);return re;
}int main()
{ios::sync_with_stdio(false);cin.tie(0);cin>>n>>q;vector<int> x(n+1),w(n+1);for(int i=1;i<=n;i++) cin>>x[i]>>w[i];for(int i=1;i<=q;i++){int l,r;cin>>l>>r;queries[r].push_back(mp(l,i));}stack<int> stk;for(int i=1;i<=n;i++){while(!stk.empty() && w[stk.top()]>w[i]) stk.pop();if(!stk.empty()) useful[i].push_back(stk.top());stk.push(i);}while(!stk.empty()) stk.pop();for(int i=n;i>=1;i--){while(!stk.empty() && w[stk.top()]>w[i]) stk.pop();if(!stk.empty()) useful[stk.top()].push_back(i);stk.push(i);}vector<ll> ans(q+1);//debug vector<int> ans(n+1);memset(bit,0x3f,sizeof bit);for(int r=1;r<=n;r++){for(vector<int>::iterator it=useful[r].begin();it<useful[r].end();it++){int l=*it;ll val=1ll*(x[r]-x[l])*(w[l]+w[r]);modify(l,val);}for(vector<pii>::iterator it=queries[r].begin();it<queries[r].end();it++){int l=it->first,id=it->second;ans[id]=query(l);}}for(int i=1;i<=q;i++) cout << ans[i] << endl;  //debug i<=nreturn 0;}

Codeforces Round #772 (Div. 2) CF1635ABCDEF相关推荐

  1. Codeforces Round #772 (Div. 2) D. Infinite Set (动态规划+思维)

    题目链接 https://codeforces.com/contest/1635/problem/D 题面 题意 输入一个n表示数组 aaa 的长度,然后输入一个 p,然后输入n个不同的元素,问在 [ ...

  2. Codeforces Round #772 (Div. 2) C. Differential Sorting(思维+构造)

    题目链接 https://codeforces.com/contest/1635/problem/C 题面 题意 给你一个长度为n的数组 a[i]a[i]a[i] ,我们有一种操作让 a[x]=a[y ...

  3. Codeforces Round #506 (Div. 3)

    Codeforces Round #506 (Div. 3) 实习期间事不多,对div3 面向题解和数据编程了一波 A. Many Equal Substrings 题目链接 A题就是找后缀和前缀重合 ...

  4. Codeforces Round #563 (Div. 2)/CF1174

    Codeforces Round #563 (Div. 2)/CF1174 CF1174A Ehab Fails to Be Thanos 其实就是要\(\sum\limits_{i=1}^n a_i ...

  5. 构造 Codeforces Round #302 (Div. 2) B Sea and Islands

    题目传送门 1 /* 2 题意:在n^n的海洋里是否有k块陆地 3 构造算法:按奇偶性来判断,k小于等于所有点数的一半,交叉输出L/S 4 输出完k个L后,之后全部输出S:) 5 5 10 的例子可以 ...

  6. Codeforces Round #696 (Div. 2) (A ~ E)超高质量题解(每日训练 Day.16 )

    整理的算法模板合集: ACM模板 点我看算法全家桶系列!!! 实际上是一个全新的精炼模板整合计划 Codeforces Round #696 (Div. 2) (A ~ E)超高质量题解 比赛链接:h ...

  7. Codeforces Round #712 Div.2(A ~ F) 超高质量题解(每日训练 Day.15 )

    整理的算法模板合集: ACM模板 点我看算法全家桶系列!!! 实际上是一个全新的精炼模板整合计划 Codeforces Round #712 Div.2(A ~ F) 题解 比赛链接:https:// ...

  8. Codeforces Round #701 (Div. 2) A ~ F ,6题全,超高质量良心题解【每日亿题】2021/2/13

    整理的算法模板合集: ACM模板 点我看算法全家桶系列!!! 实际上是一个全新的精炼模板整合计划 目录 A - Add and Divide B - Replace and Keep Sorted C ...

  9. Codeforces Round #700 (Div. 2) D2 Painting the Array II(最通俗易懂的贪心策略讲解)看不懂来打我 ~

    整理的算法模板合集: ACM模板 点我看算法全家桶系列!!! 实际上是一个全新的精炼模板整合计划 整场比赛的A ~ E 6题全,全部题目超高质量题解链接: Codeforces Round #700 ...

最新文章

  1. TensorRT是NVIDIA开发的深度学习推理工具,只支持推理,不支持训练 引
  2. CryEngine最新版发布,支持Vulkan API
  3. SpringMVC之源码分析--HandlerMapping(一)
  4. nema gps数据转换 matlab,GPS通信的NEMA协议与定位数据的提取.pdf
  5. linux内核参数备注
  6. mysql内存片多大_内存带宽对mysql影响多大?
  7. GPU是如何工作的?
  8. 安卓通过js与网页的H5页面进行交换
  9. python音乐下载器
  10. 【竞赛篇-申报平台】浙江省国创(大创)平台里导出的word显示不出图片、右边界溢出页面,图片空间不足的解决办法
  11. 计算机设备全年销售表,2021年计算机机房设备行业财务部门表格模板汇总 .pdf
  12. 鸿蒙系统桌面建文件夹,怎样把桌面上的文件放在一个文件夹里
  13. 新一配:perl循环调用python爬虫批量下载喜马拉雅音频
  14. MCU设计之 - 启动模式(Boot0Boot1)
  15. 我的世界基岩版好还是java版好_【Minecraft/我的世界】Java版和基岩版的区别(1)...
  16. python如何调用谷歌搜图api_python爬虫——selenium+chrome使用代理
  17. 小程序用户头像昵称获取不到解决办法
  18. Linux时间 新纪元 epoch time
  19. Linux进程监视器——htop详解
  20. Android-Studio与Python环境配置

热门文章

  1. 哈工程计算机专硕考研经验贴
  2. 04.第五章、范围管理
  3. 一些国内可用的高质量壁纸网站,免翻~
  4. highchart 组织结构图
  5. 全面了解光纤跳线的应用及使用注意事项
  6. 企业财务管理信息化现状思考与探索
  7. 计算机转换几种,文件转换 篇一:有多少种文件格式转换的方法,你造吗?
  8. 李岳恒:2020年的经济趋势研判
  9. 《SiamMask:Fast Online Object Tracking and Segmentation:A Unifying Approach》论文笔记
  10. 小鸡G4工程款 上手体验