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

8.29

最后一天在高中自习

下午一到调了 \(1.5h\) 的大模拟

就是昨天那道

然后得了 \(55pts\)

继续放代码尸体

CODE
#include<bits/stdc++.h>
#define fst first
#define sec second
#define mkp(a,b) make_pair(a,b)
#define usetime() (double)clock () / CLOCKS_PER_SEC * 1000.0
using namespace std;
typedef long long LL;
typedef pair<LL,int> pii;
const int maxn=155;
void read(int& x){char c;bool f=0;while((c=getchar())<48) f|=(c==45);x=c-48;while((c=getchar())>47) x=(x<<3)+(x<<1)+c-48;x=(f ? -x : x);
}
void read(LL& x){char c;bool f=0;while((c=getchar())<48) f|=(c==45);x=c-48;while((c=getchar())>47) x=(x<<3)+(x<<1)+c-48;x=(f ? -x : x);
}
struct edge{string name;int to;
};
pii d[maxn];
vector<edge> mp[maxn];
unordered_map<string,int> m;
unordered_map<string,pii> var;
set<pii> va;
int n;
int tot=0;
LL len=0;
LL mceil(LL x,LL y){if(x%y==0) return x/y;else return x/y+1;
}
int main(){freopen("P9754_7.in","r",stdin);freopen("wwa.out","w",stdout);read(n);int op,p;string s,a,b;LL ar;m["byte"]=++tot,d[tot]=mkp(1,1);m["short"]=++tot,d[tot]=mkp(2,2);m["int"]=++tot,d[tot]=mkp(4,4);m["long"]=++tot,d[tot]=mkp(8,8);//空间大小+对齐要求while(n--){read(op);if(op==1){cin>>s;m[s]=++tot;read(p);LL lst=0;d[tot].sec=0;while(p--){cin>>a>>b;mp[tot].push_back((edge){b,m[a]});d[tot].sec=max(d[tot].sec,d[m[a]].sec);lst=mceil(lst,d[m[a]].sec)*d[m[a]].sec+d[m[a]].fst;}d[tot].fst=lst;//cout<<"ans=";printf("%lld %d\n",d[tot].fst,d[tot].sec);}if(op==2){cin>>a>>b;var[b]=mkp(mceil(len,d[m[a]].sec)*d[m[a]].sec,m[a]);va.insert(var[b]);len=var[b].fst+d[m[a]].fst;//cout<<"ans=";printf("%lld\n",var[b].fst);}if(op==3){cin>>s;//cout<<"ans=";s.append(1,'.');int k=0;a.clear();while(s[k]!='.') a.append(1,s[k++]);int now=var[a].sec;LL ans=var[a].fst;a.clear();for(int i=k+1;i<(int)s.size();i++){if(s[i]=='.'){for(int j=0;j<(int)mp[now].size();j++){int v=mp[now][j].to;if(mp[now][j].name==a){ans=mceil(ans,d[v].sec)*d[v].sec;now=v;break;}else{ans=mceil(ans,d[v].sec)*d[v].sec+d[v].fst;}}a.clear();}else{a.append(1,s[i]);}}if(ans==1516||ans==2536) cout<<"wa::";printf("%lld\n",ans);}if(op==4){read(ar);//cout<<"ans=";vector<string> v;LL l=0;int now=0;for(auto i=va.begin();i!=va.end();i++){if(i->fst<=ar) l=i->fst,now=i->sec;else break;}for(auto i=var.begin();i!=var.end();i++){if(i->sec.fst==l){v.push_back(i->fst);break;}}if(!now){cout<<"ERR\n";continue;}while(now>4){int tp=-1;for(int j=0;j<(int)mp[now].size();j++){int v=mp[now][j].to;LL li=mceil(l,d[v].sec)*d[v].sec+d[v].fst;if(li>ar){l=mceil(l,d[v].sec)*d[v].sec,tp=j;break;}else{l=li;}}if(tp<0){l=-1e18;break;}v.push_back(mp[now][tp].name);now=mp[now][tp].to;}//cout<<now<<' '<<ar-l+1<<endl;l=mceil(l,d[now].sec)*d[now].sec;if(l>ar||ar-l>=d[now].fst){cout<<"ERR";}else{cout<<v[0];for(int i=1;i<(int)v.size();i++){cout<<'.'<<v[i];}}putchar('\n');}}return 0;
}
//^o^

然后打算去打比赛,把四题看了一遍

大概都是比较新的题型

最近还是以备考CSP为主,所以又写真题去了

P8818

简单博弈论,但实现有难度

先手要积最大,讨论以下几种情况

一,后手只有正数

1.先手没有正数,那么选最大的负数,后手选最大的正数

2.先手有正数,那么选最大的正数,后手选最小的正数

二,后手只有负数

1.先手没有负数,那么选最小的正数,后手选最大的正数

2.先手有负数,那么选最小的负数,后手选最大的正数

二,后手既有正数,又有负数

1.若先手有负数,则可以选最大的负数,后手选最大的正数

2.若先手有正数,则可以选最小的正数,后手选最小的负数

两者中取其乘积最大者

再考虑有 \(0\) 的情况:

当先手有 \(0\) 的时候

此时若出现无论先手其他的任何数,后手都能使其变为负数时,使用 \(0\)

当后手有 \(0\) 的时候

此时若出现先手旋完后,后手无论接其他的任何数都会使积变为正数,使用 \(0\)

发现我们只需要把 \(0\) 当作最大的负数,最小的正数,就可以在上面的分类讨论中解决 \(0\) 的问题了

也就是说,需要假定 \(0\) 既是正数,也是负数

综上,我们只需要求区间的负数最大,最小,正数最大,最小值即可

用st表或者线段树都可以

此处使用线段树

CODE
#include<bits/stdc++.h>
#define usetime() (double)clock () / CLOCKS_PER_SEC * 1000.0
using namespace std;
typedef long long LL;
const int maxn=2.1e5+5;
const int inf=2e9+1;
void read(int& x){char c;bool f=0;while((c=getchar())<48) f|=(c==45);x=c-48;while((c=getchar())>47) x=(x<<3)+(x<<1)+c-48;x=(f ? -x : x);
}
int t1[maxn<<2],t2[maxn<<2],t3[maxn<<2],t4[maxn<<2];
//正数中的最小值,最大值,负数中的最大值,最小值
int n,m,q;
int a[maxn];
void push_up(int u){t1[u]=min(t1[u<<1],t1[u<<1|1]);t2[u]=max(t2[u<<1],t2[u<<1|1]);t3[u]=max(t3[u<<1],t3[u<<1|1]);t4[u]=min(t4[u<<1],t4[u<<1|1]);
}
void build(int l=1,int r=n+m,int u=1){if(l==r){if(a[l]>=0) t1[u]=a[l],t2[u]=a[l];if(a[l]<=0) t3[u]=a[l],t4[u]=a[l];return;}int mid=(l+r)>>1;build(l,mid,u<<1),build(mid+1,r,u<<1|1);push_up(u);
}
int query1(int L,int R,int l=1,int r=n+m,int u=1){if(r<L||l>R) return inf;if(l>=L&&r<=R) return t1[u];int mid=(l+r)>>1;return min(query1(L,R,l,mid,u<<1),query1(L,R,mid+1,r,u<<1|1));
}
int query2(int L,int R,int l=1,int r=n+m,int u=1){if(r<L||l>R) return -inf;if(l>=L&&r<=R) return t2[u];int mid=(l+r)>>1;return max(query2(L,R,l,mid,u<<1),query2(L,R,mid+1,r,u<<1|1));
}
int query3(int L,int R,int l=1,int r=n+m,int u=1){if(r<L||l>R) return -inf;if(l>=L&&r<=R) return t3[u];int mid=(l+r)>>1;return max(query3(L,R,l,mid,u<<1),query3(L,R,mid+1,r,u<<1|1));
}
int query4(int L,int R,int l=1,int r=n+m,int u=1){if(r<L||l>R) return inf;if(l>=L&&r<=R) return t4[u];int mid=(l+r)>>1;return min(query4(L,R,l,mid,u<<1),query4(L,R,mid+1,r,u<<1|1));
}
int main(){read(n),read(m),read(q);for(int i=1;i<=n;i++){read(a[i]);}for(int i=n+1;i<=n+m;i++){read(a[i]);}int s=(n+m+10)<<2;fill(t1,t1+s,inf);fill(t2,t2+s,-inf);fill(t3,t3+s,-inf);fill(t4,t4+s,inf);build();int l1,r1,l2,r2;while(q--){read(l1),read(r1),read(l2),read(r2);l2+=n,r2+=n;LL ans=0;//query1正数最小值//query2正数最大值//query3负数最大值//query4负数最小值if(query3(l2,r2)==-inf){//对面没有负数,即全是正数if(query1(l1,r1)==inf){//我没有正数,即全是负数ans=1ll*query3(l1,r1)*query2(l2,r2);//负数最大*正数最大}else{ans=1ll*query2(l1,r1)*query1(l2,r2);//正数最大*正数最小}}else if(query2(l2,r2)==-inf){//对面没有正数,即全是负数if(query4(l1,r1)==inf){//我没有负数,即全是正数ans=1ll*query1(l1,r1)*query4(l2,r2);//正数最小*负数最小}else{ans=1ll*query4(l1,r1)*query3(l2,r2);//负数最小*负数最大}}else{ans=-(1ll*inf*inf);if(query1(l1,r1)!=inf){//我有正数ans=max(ans,1ll*query1(l1,r1)*query4(l2,r2));}if(query4(l1,r1)!=inf){//我有负数ans=max(ans,1ll*query3(l1,r1)*query2(l2,r2));}//正数最小*负数最小,负数最大*正数最大}printf("%lld\n",ans);}return 0;
}
//^o^

虽然理论复杂度上,st表优于线段树

但是最优解竟然是线段树的!!!

P9744

题目

对于一个要变成 \(1\) 的位置,要么将他前面的全变成 \(0\),然后把前面所有的位置都变成 \(1\)

要么找一个比他靠后的位置,把其前面的全变成 \(0\) ,然后把该位置和其前面的所有要变 \(1\) 的地方全变成 \(1\)

要么从前一个变成 \(1\) 的地方继承过来,把两个 \(1\) 中间的部分变成 \(0\)

这样就有状态转移了,所以就是个 \(dp\)

但是注意把一个位置前的所有东西变成 \(0\) 不一定是操作 \(1\) 的原数

有可能通过操作 \(1\) 和操作 \(2\) 一起进行得到

所以先 \(dp\) 一遍把一个位置前的所有元素变成一的最少花费

CODE
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int maxn=5e5+5;
void read(int& x){char c;while((c=getchar())<48);x=c-48;while((c=getchar())>47) x=(x<<3)+(x<<1)+c-48;
}
void read(LL& x){char c;while((c=getchar())<48);x=c-48;while((c=getchar())>47) x=(x<<3)+(x<<1)+c-48;
}
int a[maxn],b[maxn],c[maxn];
int f[maxn],v[maxn];
LL s[maxn];
int n,m,q;
int main(){read(n);for(int i=1;i<=n;i++) read(a[i]);for(int i=1;i<=n;i++) read(b[i]);for(int i=1;i<=n;i++) read(c[i]);for(int i=1;i<=n;i++){f[i]=min(a[i],f[i-1]+b[i]);s[i]=s[i-1]+b[i];}read(q);LL ans,sum;while(q--){read(m);for(int i=1;i<=m;i++){read(v[i]);}ans=0,sum=0;for(int i=1;i<=m;i++){ans=min({f[v[i]]+sum+c[v[i]],f[v[i]-1]+sum,ans+s[v[i]-1]-s[v[i-1]]});sum+=c[v[i]];}printf("%lld\n",min(ans+s[n]-s[v[m]],f[n]+sum));}return 0;
}
//^o^

今天还去看了团队的题,做了挺久的实验,具体不能透露

说不定是明年某场洛谷团队赛里的题呢?

http://www.sczhlp.com/news/50432/

相关文章:

  • 软件架构风格演化与分类全景图
  • 网站自然优化营销型网站建设哪个好
  • 响应式网站的尺寸临海市网站建设
  • 德阳建设银行招聘网站营销网站型建设多少钱
  • 济南网站排名公司自己做视频网站怎么让加载速度变快
  • 泉州网页网站制作建设工程敎育那个网站
  • 注册网站的步骤三个关键词介绍自己
  • 阿里巴巴网站icp编号怎么查行业网站搭建
  • 1688会提供网站建设企业网站建设的费用
  • 浙江省工程建设管理协会网站用哪个程序做网站收录好
  • 织梦网站管理安装网站图标用代码代替
  • 豆粕2601
  • 网站管理建设工作报告电脑网页设计教程
  • 如何使用 frp 在内网中搭建多个服务?
  • 【视频笔记】Elastic Search是什么?Lucene是什么?架构是怎么样的?
  • 方法数码做的网站怎么样哈尔滨市招标网官网
  • 西安免费做网站哪家好有什么平台做网站比较好
  • 网站dns刷新阿里云云服务器官网
  • 杭州企业如何建网站自媒体网站wordpress
  • 做个网站多少钱区网站建设
  • 分类信息网站推广的意义邓砚谷电子商务网站建设
  • 老网站改版做别的镇江网页设计培训
  • 便捷的邢台做网站做网站好公司哪家好
  • 广告公司广告语简洁温州seo优化公司
  • 题解:P10878 [JRKSJ R9] 在相思树下 III
  • 潍坊滨海开发区建设局网站2345浏览器网站
  • 类似wordpress的网站专业做高校网站群管理系统
  • 无极网站免费观看开发什么app有前景
  • 深圳定制网站公司wordpress怎么做伪静态页面
  • php医院网站开发兼职下载教学设计的网站