2019.9.16 csp-s模拟测试44 反思总结
虽然说好像没有什么写这个的价值OAO
来了来了来写总结了,不能怨任何东西,就是自己垃圾x
开题顺序又和主流背道而驰,先一头扎进了公认最迷的T2,瞎搞两个小时头铁出来,然后T1和T3爆炸。基础很差,全靠瞎蒙,能力不足,不如滚蛋。
T1:D
发现对于一个长为n的序列,从右端点开始往回和前面的数依次求gcd最多不超过logn个,原因是每次的gcd若缩小则一定除以2。那么从前往后传递gcd,需要维护的gcd也不超过logn个。
于是从1~n枚举序列右端点,每一次把当前存在的gcd分别和新的右端点求gcd,用map映射存下这个gcd当前存在的这段序列中它的最小左端点,尝试更新答案。
不要忘了记录当前的右端点x
时间复杂度是O(nlog2n),当然有标准的O(nlogn)做法啦,但我懒嘛。
代码:
#include<iostream>
#include<cstdio>
#include<map>
using namespace std;
int n;
long long a[];
map<long long,int>mp,m;
map<long long,int>::iterator it;
long long ans;
long long GCD(long long a,long long b){
return !b?a:GCD(b,a%b);
}
int main()
{
scanf("%d",&n);
for(int i=;i<=n;i++){
scanf("%lld",&a[i]);
ans=max(ans,a[i]);
for(it=m.begin();it!=m.end();it++){
long long gcd=GCD(a[i],it->first);
if(gcd*(i-it->second+)>ans)ans=gcd*(i-it->second+);
if(!mp.count(gcd))mp[gcd]=it->second;
else mp[gcd]=min(mp[gcd],it->second);
}
if(!mp.count(a[i]))mp[a[i]]=i;
m=mp;
mp.clear();
}
printf("%lld",ans);
return ;
}
谜一样的比较大小:D
总之稍微记一下定义迭代器以及gcd不超过logn个的定理…
T2:E
说得简单一点,考虑两种情况。一种是最大最小两个球同色,另一种是异色。
异色的话假设最大值蓝色,最小值红色,那么要让两边的差都尽量小,直接把每一组的大值染蓝小值染红就OK了。
同色要麻烦一些,把各个组按小值从小到大排序,然后依次把同一组大小值反色,更新答案。假设最大值最小值都是蓝色,这样依次操作的时候红球的最大最小值是不降的,而翻转以后上一组最大最小值已经计算过了,不影响答案。这样解释有点玄学,但是自己举了几组例子好像没有反例,就试着写了一下,居然过了……
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
int n;
long long rmin=1e18,rmax,bmin=1e18,bmax,r,b;
long long ans=1e18,minn=1e18,maxx,posmin,posmax;
struct node{
long long a,b;
}x[];
bool cmp(node a,node b){
if(a.a==b.a)return a.b<b.b;
else return a.a<b.a;
}
int main()
{
scanf("%d",&n);
for(int i=;i<=n;i++){
scanf("%lld%lld",&x[i].a,&x[i].b);
if(x[i].a>x[i].b)swap(x[i].a,x[i].b);
rmin=min(x[i].a,rmin);
rmax=max(x[i].a,rmax);
bmin=min(x[i].b,bmin);
bmax=max(x[i].b,bmax);
if(x[i].a<minn){
minn=x[i].a;
posmin=i;
}
if(x[i].b>maxx){
maxx=x[i].b;
posmax=i;
}
}
ans=(rmax-rmin)*(bmax-bmin);
if(posmin==posmax)printf("%lld",ans);
else{
sort(x+,x+n+,cmp);
bmin=minn,bmax=maxx;
rmax=max(x[n].a,x[].b);
minn=x[].b;
rmin=min(x[].b,x[].a);
long long ans1=rmax-rmin;
for(int i=;i<n;i++){
rmax=max(rmax,x[i].b);
rmin=min(min(x[i].b,x[i+].a),minn);
minn=min(minn,x[i].b);
ans1=min(ans1,rmax-rmin);
}
ans=min(ans,ans1*(bmax-bmin));
printf("%lld",ans);
}
return ;
}
玄学代码
T3:F
你好,线段树优化DP,下一个。
说实话我连简单的三十分DP都没想出来,我大约是个睿智。不我应该自信地拿掉大约这两个字,毕竟你看垃圾就是垃圾,没什么好说的。
写出简单的转移式,f(i,j)中i为当前操作到第i个其中一个指针在pi,j为另一个指针在j处。
f(i,j)=f(i-1,j)+|pi-pi-1|,假如从上一个pi转移过来
f(i,pi-1)=f(i-1,j)+|pi-j|,假如从上一个j转移过来。
然后发现可以用线段树来维护,第一个转移式就是区间加,第二个转移式要维护最小fj-j和fj+j值,每次拆开绝对值根据正负查询。
注意开头的时候要先把a、b两处的f值维护成“第一个操作从b转移来”和“第一个操作从a转移来”,然后从第二次操作开始。因为对于p1来说,上一次移动的位置可以是aa也可以是bb。不写明白这个居然还有八十分:D
#include<iostream>
#include<cstdio>
#include<cmath>
using namespace std;
long long inf=1e18;
int n,q,aa,bb,lst;
struct node{
int l,r;
long long min1,min2,f,add;
}a[];
void build(int p,int l,int r){
a[p].l=l,a[p].r=r;
a[p].f=a[p].min1=a[p].min2=inf;
if(l==r)return;
int mid=(l+r)/;
build(p*,l,mid);
build(p*+,mid+,r);
}
void update(int p){
if(a[p].add){
a[p*].add+=a[p].add;
a[p*+].add+=a[p].add;
a[p*].min1+=a[p].add;
a[p*+].min1+=a[p].add;
a[p*].min2+=a[p].add;
a[p*+].min2+=a[p].add;
a[p*].f+=a[p].add;
a[p*+].f+=a[p].add;
a[p].add=;
}
}
void change(int p,int l,int r,long long val){
if(l<=a[p].l&&a[p].r<=r){
a[p].f=min(a[p].f,val);
a[p].min1=a[p].f-l;
a[p].min2=a[p].f+l;
return;
}
update(p);
int mid=(a[p].l+a[p].r)/;
if(l<=mid)change(p*,l,r,val);
if(r>mid)change(p*+,l,r,val);
a[p].min1=min(a[p*].min1,a[p*+].min1);
a[p].min2=min(a[p*].min2,a[p*+].min2);
a[p].f=min(a[p*].f,a[p*+].f);
}
void change1(int p,int l,int r,long long val){
if(l<=a[p].l&&a[p].r<=r){
a[p].add+=val;
a[p].min1+=val;
a[p].min2+=val;
a[p].f+=val;
return;
}
update(p);
int mid=(a[p].l+a[p].r)/;
if(l<=mid)change1(p*,l,r,val);
if(r>mid)change1(p*+,l,r,val);
a[p].min1=min(a[p*].min1,a[p*+].min1);
a[p].min2=min(a[p*].min2,a[p*+].min2);
a[p].f=min(a[p*].f,a[p*+].f);
}
long long query1(int p,int l,int r){
if(l<=a[p].l&&a[p].r<=r){
return a[p].min1;
}
update(p);
int mid=(a[p].l+a[p].r)/;
long long val=inf;
if(l<=mid)val=min(val,query1(p*,l,r));
if(r>mid)val=min(val,query1(p*+,l,r));
a[p].min1=min(a[p*].min1,a[p*+].min1);
a[p].min2=min(a[p*].min2,a[p*+].min2);
a[p].f=min(a[p*].f,a[p*+].f);
return val;
}
long long query2(int p,int l,int r){
if(l<=a[p].l&&a[p].r<=r){
return a[p].min2;
}
update(p);
int mid=(a[p].l+a[p].r)/;
long long val=inf;
if(l<=mid)val=min(val,query2(p*,l,r));
if(r>mid)val=min(val,query2(p*+,l,r));
a[p].min1=min(a[p*].min1,a[p*+].min1);
a[p].min2=min(a[p*].min2,a[p*+].min2);
a[p].f=min(a[p*].f,a[p*+].f);
return val;
}
long long query(int p,int l,int r){
if(l<=a[p].l&&a[p].r<=r){
return a[p].f;
}
update(p);
int mid=(a[p].l+a[p].r)/;
long long val=inf;
if(l<=mid)val=min(val,query(p*,l,r));
if(r>mid)val=min(val,query(p*+,l,r));
a[p].min1=min(a[p*].min1,a[p*+].min1);
a[p].min2=min(a[p*].min2,a[p*+].min2);
a[p].f=min(a[p*].f,a[p*+].f);
return val;
}
int main()
{
scanf("%d%d%d%d",&n,&q,&aa,&bb);
build(,,n);
scanf("%d",&lst);
change(,aa,aa,abs(lst-bb));
change(,bb,bb,abs(lst-aa));
for(int i=,x;i<=q;i++){
scanf("%d",&x);
long long num1=query1(,,x);
long long num2=query2(,x,n);
long long num=min(num1+x,num2-x);
change1(,,n,(long long)abs(x-lst));
change(,lst,lst,num);
lst=x;
}
printf("%lld",query(,,n));
return ;
}
写得贼麻烦的代码
晚上好,今天墨雨笙小朋友复习了一个重要的道理,叫作垃圾就是垃圾。这没什么问题,毕竟你就是差劲呀:D
渣滓稍微活一活就知足吧
2019.9.16 csp-s模拟测试44 反思总结的更多相关文章
- 2019.8.3 [HZOI]NOIP模拟测试12 C. 分组
2019.8.3 [HZOI]NOIP模拟测试12 C. 分组 全场比赛题解:https://pan.baidu.com/s/1eSAMuXk 刚看这题觉得很难,于是数据点分治 k只有1和2两种,分别 ...
- 2019.8.3 [HZOI]NOIP模拟测试12 B. 数颜色
2019.8.3 [HZOI]NOIP模拟测试12 B. 数颜色 全场比赛题解:https://pan.baidu.com/s/1eSAMuXk 数据结构学傻的做法: 对每种颜色开动态开点线段树直接维 ...
- 2019.8.3 [HZOI]NOIP模拟测试12 A. 斐波那契(fibonacci)
2019.8.3 [HZOI]NOIP模拟测试12 A. 斐波那契(fibonacci) 全场比赛题解:https://pan.baidu.com/s/1eSAMuXk 找规律 找两个节点的lca,需 ...
- 2019.8.9 NOIP模拟测试15 反思总结
日常爆炸,考得一次比一次差XD 可能还是被身体拖慢了学习的进度吧,虽然按理来说没有影响.大家听的我也听过,大家学的我也没有缺勤多少次. 那么果然还是能力问题吗……? 虽然不愿意承认,但显然就是这样.对 ...
- 2019.8.14 NOIP模拟测试21 反思总结
模拟测试20的还没改完先咕着 各种细节问题=错失190pts T1大约三分钟搞出了式子,迅速码完,T2写了一半的时候怕最后被卡评测滚去交了,然后右端点没有初始化为n…但是这样还有80pts,而我后来还 ...
- 2019.8.1 NOIP模拟测试11 反思总结
延迟了一天来补一个反思总结 急匆匆赶回来考试,我们这边大家的状态都稍微有一点差,不过最后的成绩总体来看好像还不错XD 其实这次拿分的大都是暴力[?],除了某些专注于某道题的人以及远程爆踩我们的某学车神 ...
- csp-s模拟测试44「D·E·F」
用心出题,用脚造数据 乱搞场 1 #include<bits/stdc++.h> 2 #define re register 3 #define int long long 4 #defi ...
- 2019.8.3 NOIP模拟测试12 反思总结【P3938 斐波那契,P3939 数颜色,P3940 分组】
[题解在下面] 早上5:50,Gekoo同学来到机房并表态:“打暴力,打暴力就对了,打出来我就赢了.” 我:深以为然. (这是个伏笔) 据说hzoi的人还差两次考试[现在是一次了]就要重新分配机房,不 ...
- 2019.10.30 csp-s模拟测试94 反思总结
头一次做图巨的模拟题OWO 自从上一次听图巨讲课然后骗了小礼物以后一直对图巨印象挺好的233 T1: 对于XY取对数=Y*log(x) 对于Y!取对数=log(1*2*3*...*Y)=log1+lo ...
随机推荐
- HDU - 6128
题意略: 题解:二次剩余板子题 //#pragma GCC optimize(2) //#pragma GCC optimize(3) //#pragma GCC optimize(4) //#pra ...
- csps-s模拟测试60嘟嘟噜,天才绅士少女助手克里斯蒂娜,凤凰院凶真题解
题面:https://www.cnblogs.com/Juve/articles/11625190.html 嘟嘟噜: 约瑟夫问题 第一种递归的容易re,但复杂度较有保证 第二种适用与n大于m的情况 ...
- css过渡属性transition简单示例
2.transition 简单实例 demo1→在线预览源代码 效果 demo2→在线预览源代码 效果 demo3→在线预览源代码 效果
- Spring MVC(八)--控制器接受简单列表参数
有些场景下需要向后台传递一个数组,比如批量删除传多个ID的情况,可以使用数组传递,数组中的ID元素为简单类型,即基本类型. 现在我的测试场景是:要从数据库中查询minId<id<maxId ...
- 使用Windows任务计划程序和Python备份Mysql数据库
目标:每日定时自动备份Mysql数据库 方案: 1.安装Python: 使用的Python版本是Python3.7.1,下载地址:https://www.python.org/downloads/re ...
- es6 Promise 异步函数调用
开发很多的时候需要异步操作,常用的做法就是用回调函数,假如需要一连串的调用,并且后面一个调用依赖前一个返回的结果的时候,就得多层嵌套回调函数,比如下面这种情况: $('.animateEle').an ...
- [Bzoj3696]化合物【暴力+树形Dp】
Online Judge:Bzoj3696 Label:暴力,树形Dp 题目描述 首长NOI惨跪,于是去念文化课了.现在,他面对一道化学题. 这题的来源是因为在一个奇怪的学校两个化竞党在玩一个奇怪的博 ...
- virtualbox 启动虚拟机提示Cannot load R0 module
Cannot load R0 module C:\Program Files\Oracle\VirtualBox/VBoxDDR0.r0: SUPR3LoadModule: supLoadModule ...
- html常用标签详解5-表格标签
表格标签(如果有不对的,请大家多多指正.谢谢!) 1.总的表格标签概览 <table><!--表格标签start--> <caption></caption& ...
- sudo apt-get update报错E: 部分索引文件下载失败。如果忽略它们,那将转而使用旧的索引文件。
解决方案1: 将对应的PPA删除掉即可 cd /etc/apt/suorces.list.d mv **.list **.list.bak 解决方案2: 更改源 cp /etc/apt/source_ ...