2020 年第一届辽宁省大学生程序设计竞赛

比赛经历:摸鱼划水了一个多小时又是只会签到,看来还得提升自己的解题能力写了六题

补题:E线段树维和区间平方和,比较经典好久没写过线段树了傻了,注意维护lazy

           J计算几何,看来得提上日程了,用叉积判断位置

           k题意看起来难爆了,没想到竟然做法如此优秀,所以有些题还是得多尝试

目录

A.组队分配

B.两点距离

C.轮到谁了?

E.线段树

F.最长回文串

G.管管的幸运数字

I.鸽子的整数运算

J.鸽者文明的三体问题

K.xor


A.组队分配

文字游戏

注意有些简单题,题目说法就是暗藏玄机,比如本题就是如此,注意按照排名升序,同时注意到内部排序是用降序

int t,n,m;
struct code{string s;int x;bool operator<(const code&t)const{return x<t.x;}
}e[N];void solve(){cin>>n;for(int i=1;i<=3*n;i++){string s; cin>>s;int x; cin>>x;e[i]={s,x};}sort(e+1,e+1+3*n);int cnt = 0;for(int i=1;i<=3*n;i+=3,cnt++){auto [s1,x1]=e[i];auto [s2,x2]=e[i+1];auto [s3,x3]=e[i+2];cout << "ACM-" << cnt << ' ' << s3 << ' ' << s2 << ' ' << s1 << endl;}return ;
}

B.两点距离

小小思考一手

注意题目定义我们可以发现两个点之间最大的距离就是2(分别到1),最小的距离就是__gcd,同时注意在一起即可,这种题要留个心眼想全再提交

void solve(){cin>>n>>m;while(m--){int x,y; cin>>x>>y;if(x>y) swap(x,y);if(x==y){cout << 0 << endl;continue;}cout << min(2,__gcd(x,y)) << endl;}return ;
}

C.轮到谁了?

斐波那契数列

通过兔子问题以及简单分析可以得知是斐波那契问题,但是即使没得到这个结论我们可以按照要求模拟,定义a,b,c为成年的,一个月,两个月的兔子来模拟即可

void solve(){cin>>n>>m;int a = 1 ,b = 0 , c = 0;// 表示成年有多少 一个月的有多少 两个月的有多少for(int i=3;i<=n;i++){a = a + c; // 表示上次两个月到现在已经成年了 c = b; // 一个月变两个月b = a; //a %= m;b %= m;c %= m;}int ans = ((a+b+c-1)%m+m)%m; // 转化为编号cout << ans << endl;return ;
}

E.线段树

区间平方和

注意只要是区间问题中出现一个式子,我们都需要对式子进行推演变形,变成有利于我们做计算的,可以按照经验,一般可以为前缀和做差,预处理,莫队,线段树维护等,对于本题进行推理之和可以得到(\sum_{i=l}^ra_i *\sum_{i=l}^ra_i - \sum_{i=l}^r{a_i}^2 )/2

j接着我们就是维护区间和 和区间平方和,同时题目要求的区间修改乘法和加法,我们可以依靠先对乘法处理,后面的加法*mul,同时维护,对于平方和对式子变化得到

sum2*mul + 2*add*sum1*mul + (r-l+1)*add

sum1 表示区间和,sum2表示区间平方和,注意到乘一个数之后再做加法,所以先乘之后sum1会变化,所以sum1需要乘mul,sum1的变化同上

LL w[N];
struct code{int l,r;LL sum1,sum2; // 表示 总和LL add,mul; // 表示平方和
}tr[4*N];void eval(code&u,LL add,LL mul){u.sum2=(u.sum2*mul%p*mul%p+2*u.sum1*mul%p*add%p+(LL)(u.r-u.l+1)*add%p*add%p)%p;u.sum1=((LL)u.sum1*mul%p+(LL)(u.r-u.l+1)*add%p)%p;u.mul=(LL)(u.mul)%p*mul%p;u.add=((LL)u.add%p*mul%p+add)%p;
}void pushup(code&u,code&l,code&r){u.sum1 = (l.sum1 + r.sum1)%p;u.sum2 = (l.sum2 + r.sum2)%p;
}void pushdown(code&u,code&l,code&r){eval(l,u.add,u.mul);eval(r,u.add,u.mul);u.add=0,u.mul=1;
}void pushup(int u){pushup(tr[u],tr[u<<1],tr[u<<1|1]);
}void pushdown(int u){pushdown(tr[u],tr[u<<1],tr[u<<1|1]);
}void build(int u,int l,int r){if(l==r){tr[u]={l,r,w[l],w[l]*w[l]%p};return ;}tr[u]={l,r,0,0,0,1};int mid=l+r>>1;build(u<<1,l,mid),build(u<<1|1,mid+1,r);pushup(u);
}void modify(int u,int l,int r,int mul,int add){if(tr[u].l>= l && tr[u].r<=r){eval(tr[u],add,mul);return ;}pushdown(u);int mid=tr[u].l+tr[u].r>>1;if(l<=mid) modify(u<<1,l,r,mul,add);if(r>mid) modify(u<<1|1,l,r,mul,add);pushup(u);
}code query(int u,int l,int r){if(tr[u].l>=l && tr[u].r<=r){return tr[u];}pushdown(u);int mid=tr[u].l+tr[u].r>>1;if(r<=mid) return query(u<<1,l,r);else if(l>mid) return query(u<<1|1,l,r);else{code res;code ll=query(u<<1,l,r);code rr=query(u<<1|1,l,r);pushup(res,ll,rr);return res;}
}
void solve(){auto qmi = [&](LL a,LL b,LL p){LL res = 1;while(b){if(b&1) res=res*a%p;b>>=1;a=a*a%p;}return res;};cin>>n>>m>>p;LL inv2 = qmi(2,p-2,p);for(int i=1;i<=n;i++) cin>>w[i],w[i]%=p;build(1,1,n);while(m--){int op,l,r,v; cin>>op>>l>>r;if(op==1){cin>>v; v%=p;modify(1,l,r,1,v);}else if(op==2){cin>>v; v%=p;modify(1,l,r,v,0);}else{code t = query(1,l,r);LL ans1 = t.sum1*t.sum1%p;LL ans2 = t.sum2;LL ans = ans1 - ans2;ans *= inv2;ans = (ans%p+p)%p;cout << ans << endl;}}return ;
}

F.最长回文串

简单贪心

题目咋一看很难,但是最忌讳就是咋一看可能就看错很多信息,对于有些字符串可以丢弃,对于每个字符串字符可以重新排列,最后字符串可以重新排列最后构成的最长的回文串

分析得出 一个串留下来的条件 

1.有一个和他一模一样的放两边构成回文

2.当前这个可以作为回文串中间位置

我们直接排序判断是不是一样即可,对于中间的判断其奇数个数是不是小于等于1即可

void solve(){unordered_map<string,int> mp;cin>>n>>m;for(int i=1;i<=n;i++){string s; cin>>s;sort(s.begin(),s.end());mp[s]++;}int ans = 0;vector<string> a;for(auto&[v,w]:mp){ans += (int)v.size()*(w-(w&1));if(w&1) a.push_back(v);}int add = 0;for(auto&v:a){vector<int> cnt(26);for(auto&c:v) cnt[c-'a']++;int odd = 0;for(int i=0;i<26;i++) if(cnt[i]&1) odd++;if(odd<=1){add = m; break;}}ans += add;cout << ans << endl;return ;
}

G.管管的幸运数字

暴力

有些时候可能有好的做法,但是如果你发现你是用暴力的做法时间复杂度是可以轻松过去的时候也可以考虑暴力,比如本题我们可以得出结论每一个数的左右移动次数不会超过10000,轻松可以跑过直接暴力即可,首先用线性筛,然后直接左右遍历

bool st[N];
int p[N],cnt;void get(){for(int i=2;i<M;i++){if(!st[i]) p[cnt++]=i;for(int j=0;p[j]<M/i;j++){st[i*p[j]]=true;if(i%p[j]==0) break;}}
}
void solve(){cin>>n;if(!st[n]){cout << "YES" << endl;return ;}int ans = N;for(int i=n;i>=1;i--){if(!st[i]){ans = min(ans,n-i);break;}}for(int i=n+1;i;i++){if(!st[i]){ans = min(ans,i-n);break;}}cout << ans << endl;return ;
}

I.鸽子的整数运算

纯签到

没什么好说的直接模拟

void solve(){int op,a,b; cin>>op>>a>>b;int ans = 0;if(op==1) ans = a+b;if(op==2) ans = a-b;if(op==3) ans = a*b;if(op==4) ans =a/b;cout << ans << endl;return ;
}

J.鸽者文明的三体问题

叉积处理内外

我们可以考虑直接使用叉积来判断是不是在三角形的同一侧即可

struct code{int x[3],y[3];
}e[N];void solve(){cin>>n>>m;for(int i=1;i<=n;i++){for(int j=0;j<3;j++){cin>>e[i].x[j]>>e[i].y[j];}}auto check = [&](int x,int y,code t){auto get = [&](int x1,int y1,int x2,int y2){LL ans = (LL)x1*y2 - (LL)x2*y1;return ans;};int t1 = get(x-t.x[0],y-t.y[0],t.x[1]-t.x[0],t.y[1]-t.y[0]);int t2 = get(x-t.x[1],y-t.y[1],t.x[2]-t.x[1],t.y[2]-t.y[1]);int t3 = get(x-t.x[2],y-t.y[2],t.x[0]-t.x[2],t.y[0]-t.y[2]);return (t1>0) == (t2>0) and (t2>0)==(t3>0);  };while(m--){int x,y; cin>>x>>y;int ans = 0;for(int i=1;i<=n;i++) if(check(x,y,e[i])) ans++;cout << (ans&1 ? "Yes" : "No") << endl;}return ;
}

K.xor

妙妙dp

对于本题题目看起来十分复杂,我们看看能不能简单处理,明显的是一个dp同时时间复杂度只能在nlogn级别,我们直接来定义一手dp[i]表示前i个构成符合题意的方案数,当前异或为a[i]我们来看当前这个数可以从什么状态转移过来,前缀中符合要求的能dp[j],异或为x^a[i]的,注意到我们无法从某一个位置转移过来,但是我们要的是异或为x^a[i]的位置,我们可以再定义一个dp,注意到数据范围可以开map来处理,定义为当前数为x的符合题目要求的方案数即可,map[x] 从当前数是x的位置转移过来不重不漏

int a[N],dp[N];void solve(){cin>>n>>x;map<int,int> mp;mp[0]=1;for(int i=1;i<=n;i++){cin>>a[i];a[i] ^= a[i-1];dp[i] = mp[x^a[i]];mp[a[i]] += dp[i];dp[i] %= mod;mp[a[i]] %= mod;}cout << dp[n] << endl;return ;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/707100.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Ipython 解释器之魔法命令

文章目录 1. 性能分析 %timeit 和 %prun2. 交互式绘图 %matplotlib inline3. 查看和修改环境变量 %env4. 读取并执行外部脚本 %run5. 调试 %debug6. 代码 profiling with %lprun7. 记忆函数结果 %memit 和 %mprun8. 交互式Shell与系统命令 %shell9. 自动补全与文档查看 %autoin…

【面试干货】一个数组的倒序

【面试干货】一个数组的倒序 1、实现思想2、代码实现 &#x1f496;The Begin&#x1f496;点点关注&#xff0c;收藏不迷路&#x1f496; 1、实现思想 创建一个新的数组&#xff0c;然后将原数组的元素按相反的顺序复制到新数组中。 2、代码实现 package csdn;public class…

CentOS7使用Docker安装Redis图文教程

1.拉取Redis镜像 这里制定了版本&#xff0c;不指定默认latest最新版 docker pull redis:6.0.8提示信息如下即为下载成功 2.上传配置文件 官方配置文件&#xff08;找自己对应的版本&#xff09;&#xff1a;reids.conf 或者将如下配置文件命名为redis.conf&#xff0c;上…

副业新选择:10大程序员热门接单平台,兼职赚钱两不误!

很多程序员都想过通过副业赚取收入&#xff0c;但往往会停在接单的第一步&#xff1a;要么是因为懒拖延迟迟没有行动&#xff0c;要么因为没有选对适合自己的平台迟迟没有开张。程序员想要通过副业赚取收入&#xff0c;一定要看好这10个程序员接单平台&#xff0c;保你主业副业…

nestJs链接redis

给大家推荐一个库&#xff0c;地址:Yarn service import { Injectable } from nestjs/common; import { RedisService as RedisServices, DEFAULT_REDIS_NAMESPACE } from liaoliaots/nestjs-redis; import Redis from ioredis;Injectable() export class RedisService {priva…

玩转网络调试利器:深入剖析ip命令的强大功能

欢迎来到我的博客&#xff0c;代码的世界里&#xff0c;每一行都是一个故事 玩转网络调试利器&#xff1a;深入剖析ip命令的强大功能 前言ip命令概述网络接口管理ip地址配置路由管理邻居关系查看 前言 在我们的日常网络使用中&#xff0c;我们经常需要管理和调试网络接口、路由…

springBoot 如何让数据库读写分离

springBoot 数据库读写分离 数据库的读写分离,首先要把spring 中的自动加载的类排除掉,因为我们配置文件配置了多数据源,并且希望自己主导sql语句执行的数据库。 启动类排除自动配置 @SpringBootApplication(exclude = {DataSourceAutoConfiguration.class}) 循环引用问题…

【Linux 网络】网络编程套接字 -- 详解

⚪ 预备知识 1、理解源 IP 地址和目的 IP 地址 举例理解&#xff1a;&#xff08;唐僧西天取经&#xff09; 在 IP 数据包头部中 有两个 IP 地址&#xff0c; 分别叫做源 IP 地址 和目的 IP 地址。 如果我们的台式机或者笔记本没有 IP 地址就无法上网&#xff0c;而因为…

【2024】最新微信小程序商城源码开源版 多用户无限多开+15大功能模块

随着微信小程序市场的蓬勃发展&#xff0c;越来越多的商家和企业意识到了微信小程序作为线上销售平台的重要性。为了满足广大用户的需求&#xff0c;分享一款2024年最新微信小程序商城源码开源版&#xff0c;该版本不仅支持多用户无限多开&#xff0c;还集成了15大功能模块&…

废品回收微信小程序基于FastAdmin+ThinkPHP+UniApp

一款基于FastAdminThinkPHPUniApp开发的废品回收系统&#xff0c;适用废品回收站、再生资源回收公司上门回收使用的小程序。 一、FastAdmin框架特色功能及优势 模块化开发&#xff1a;控制器、模型、视图、JS一一对应&#xff0c;使用RequireJS进行插件机制&#xff0c;支持插…

一键抠图神器,轻松实现图片背景大变身!

在这个信息爆炸的时代&#xff0c;图片已成为人们日常交流和获取信息的重要媒介。一张精美、有趣的图片往往能吸引众多目光&#xff0c;为我们在社交媒体上赢得更多的关注。然而&#xff0c;想要打造出一张高质量的图片并非易事&#xff0c;特别是当涉及到抠图换背景等高级技巧…