2021“MINIEYE杯”中国大学生算法设计超级联赛(1)

1001 Mod, Or and Everything

题意:

对于每次输入的数字n,求(n%1)|...(n%n)的值

题解:

n%(n-i)=i,n偶数:m=(n/2-1)||n奇数:m=(n-1/2);0<=i<=m =>0|1|2|...|m

注意:

可以根据打表可知0|1|2...|m=pow(2,m上的最高数位)-1

代码:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int main(){
int t;cin>>t;
while(t--){
ll n;cin>>n;ll ans;
int i;ans=1;
for(i=1;i<=n;i++){
if(ans>=n)break;
else ans*=2;
}
i--;//n的最高数位
ans=pow(2,i-1)-1;//m的最高数位
cout<<ans<<endl;
}
return 0;
}

1002 Rocket land(待)

题意:

题解:

注意:

代码:

1003 Puzzle loop(待)

题意:

题解:

注意:

代码:

1004 Another thief in a Shop(待)

题意:

题解:

注意:

代码:

1005 Minimum spanning tree

题意:

求一个最小生成树

题解:

因为这棵树有一些特征,就是如果某个数是质数,就在前一个数的权值上加上自己x2,否则就加上自己x1。所以可以通过一个质数筛选出所有的质数,然后遍历,用一个数组存下来得到的值,之后只要直接读取就好了。

注意:

初始数据是down[2]=0

代码:

#include<bits/stdc++.h>
using namespace std;
const int maxn=1e7;
long long prime[maxn],down[maxn];bool v[maxn];
void primes()
{
memset(v,0,sizeof(v));
int m=0;//质数
for(int i=2;i<maxn;i++)
{
if(!v[i])prime[++m]=i;//质数
for(int j=1;j<=m&&prime[j]*i<=maxn;j++)
{
v[prime[j]*i]=true;//将倍数都赋给那些为合数的值
if(i%prime[j]==0)break;//已经进行过计算了
}
}
//for(int i=1;i<=m;i++)cout<<prime[i]<<" ";
}
int main(){
int t,n;
cin>>t;
primes();
down[2]=0;
for(int i=3;i<=maxn;i++){
if(v[i]==true)down[i]=down[i-1]+i;
else down[i]=down[i-1]+2*i;
}
while(t--)
{
cin>>n;
printf("%lld\n",down[n]);
}
return 0;
}

1006 Xor sum

题意

找一个连续字串异或和大于等于k,有多组则输出左边起始点最小的字串左右序号

题解

先求一个异或前缀和x,因为aba=b.所以某一段子串(n~m)的连续异或和就为x[n]^x[m],这里采用字典树的方式来维护运行,将前缀和用二进制的方式展开,插入字典树里边,去找两个数的前缀和异或>=k,记录下对应的编号,遍历下去找到最小的长度即可。

注意

因为是多组输入,所以trie[][]数组里头有可能会有之前留下的数字,所以会造成一些问题,所以要进行初始化,但是用memset会T,所以这里采用,将下一个结点的trie[][]=0的形式

代码

#include<bits/stdc++.h>
using namespace std;
const int maxn=1e5+5;
#define INF 0x3f3f3f3f
int trie[maxn*31+10][2];//将一个数转换成二进制然后丢进字典树里边去维护
int index[maxn*31+10];//对于每一个数来说他们的二进制都是31位数的形式,所以插入的时候,是一个个把他们的数位插进去,所以tot会最多加到maxn*31次
int a[maxn];
int n,m,tot;
void insert(int x,int in)
{
int p=1;
for(int k=30;~k;k--)//(-1取反为0,可作为判断条件)
{
int ch=(x>>k)&1;
if(!trie[p][ch]){
trie[p][ch]=++tot;//trie开始用的就是1,所以要往下继续找结点,即2
trie[tot][0]=trie[tot][1]=0;//下一个结点是空的
}
p=trie[p][ch];
index[p]=in;//表示这一系列的数都是第in个数的插入结果
}
}
int find(int x)//得到的是与x异或的另外一个数的最小位置
{
int p=1;int res=0;
for(int k=30;~k;k--) {
int ch = (x >> k) & 1;
if (trie[p][ch ^ 1])//遍历的是另外一个数位和x完全不一样的数字,如果那个数字存在的话,就可以直接加上1<<k
{
p = trie[p][ch ^ 1];
res += 1 << k;
if (res >= m)return index[p];
}
else p=trie[p][ch];
}
return -1;
}
void solve()
{
scanf("%d%d",&n,&m);tot=1;
a[0]=0;int len=n+1,l,r;
trie[1][0]=trie[1][1]=0;
index[1]=1;//初始状态
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
if(a[i]>=m&&len!=1){
len=1;
l=r=i;
}
a[i]^=a[i-1];
}
if(len==1){
printf("%d %d\n",l,r);
return ;
}
int mit=INF;
for(int i=1;i<=n;i++)
{
int t=find(a[i]);//因为前一个数已经被插入进去了,所以直接搜就好了
if(~t&&i-t<mit)
{
mit=i-t;
l=t+1;
r=i;
}
insert(a[i],i);
}
if(mit==INF)printf("-1\n");
else printf("%d %d\n",l,r);
}
int main()
{
int t;
cin>>t;
while(t--)
{
solve();
}
}

1007 Pass!(待)

题意

题解

注意

代码

1008 Maximal submatrix

题意

求连续的从上往下不递减的最大子矩阵的面积

题解

悬线法,通过悬线的方式,左右移动找到最大的边界,用长度乘以悬线长度,即可求出面积

单调栈

注意

开数组,稍微开大一点,这样不会越界

代码

#include<bits/stdc++.h>
using namespace std;
int t,n,m;
const int maxn=2e3+5;//注意数组不要开太小,数组越界会显示T
int mt[maxn][maxn],k[maxn][maxn],l[maxn],r[maxn];
void solve()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
scanf("%d",&mt[i][j]);
for(int i=1;i<=m;i++)
{
stack<int>s;
for(int j=1;j<=n;j++)
{
if(s.empty()||mt[j][i]>=mt[s.top()][i])s.push(j);//连续不递减
else {
while(s.size()){
k[s.top()][i]=j-1;//因为到第j位出现断层,所以,每一条这样的悬线,他们的最长延伸长度都是j-1
s.pop();
}
s.push(j);//继续递归下去
}
}
while(s.size())//如果遍历到了末端,就说明,他们到了矩形的边界处
{
k[s.top()][i]=n;
s.pop();
}
for(int j=1;j<=n;j++)
{
k[j][i]-=j-1;//表示的是从底线j上边满足不递减的长度
}
}
int ans=0;
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
l[j]=r[j]=j;//表示的是每条悬线所能移动的左右边界,滚动数组,减少空间
}
for(int j=1;j<=m;j++){
while(l[j]>1&&k[i][l[j]-1]>=k[i][j])//说明在第-1存在着一个障碍物
l[j]=l[l[j]-1];//所以它的左边界就要左移
}
for(int j=m;j;j--){
while(r[j]<m&&k[i][r[j]+1]>=k[i][j])
r[j]=r[r[j]+1];//l[j]==1||r[j]==m,表示在边界处,不需要再进行处理了
}
for(int j=1;j<=m;j++)
ans=max(ans,(r[j]-l[j]+1)*k[i][j]);
}
printf("%d\n",ans);
}
int main()
{
cin>>t;
while(t--)
{
solve();
}
return 0;
}

1009 KD-Graph

题意

将一些点分成k块,并满足每一块里边都存在<=D,块与块之间满足>=D

题解

最小生成树,通过不断寻找权值

注意

并查集利用一下路径压缩,就不会T了

代码

#include<bits/stdc++.h>
using namespace std;
int n,m,k;
const int maxn=1e6+10;
struct node{
int u,v,w;
//node(int _u,int _v,int _w):u(_u),v(_v),w(_w){}
}edge[maxn];
int f[maxn];
bool cmp(node a ,node b)
{
return a.w<b.w;
}
inline int find(int x)
{
return (x==f[x]?x:(f[x]=find(f[x])));//这里有一个路径压缩
//return x==f[x]?x:find(f[x]);
}
signed main()
{
int t;
cin>>t;
while(t--)
{
scanf("%d%d%d",&n,&m,&k);
for(int i=1;i<=n;i++)f[i]=i;
for(int i=1;i<=m;i++){
scanf("%d%d%d",&edge[i].u,&edge[i].v,&edge[i].w);
}
sort(edge+1,edge+m,cmp);
int now=n,ans=0,flag=0;//????
for(int i=1;i<=m;i++)//权值是从小到大排列的
{
if(edge[i].w!=edge[i-1].w){//说明这个得到的ans就是上一组的权值
if(now==k){//已经分成了k块
printf("%d\n",ans);
flag=1;
break;
}
}
if(find(edge[i].u)==find(edge[i].v))continue;
now--;
f[find(edge[i].u)]=find(edge[i].v);//合并
ans=edge[i].w;//得到更大的权值,毫无疑问之前的分组的权值都是小于ans的
//而其他没有并进这些块的组很明显他们之间的权值都是要大于ans的
}
if(!flag){//表示中间有好几个相同权值的点,但是不知道他们有没有被并进去,需要判断
printf("%d\n",now==k?ans:-1);
}
}
return 0;
}

1010 Zoto

题意:

注意理解题意,这里是说有n次输入,每次输入一个数(i,a[i])作为点的x,y坐标,再进行m次查询,给定两个点的横坐标和纵坐标问查询的矩阵区域里头,有多少个y坐标不同的数。

题解:

了解了莫队算法之后,这道题目就可以转换成求一个区间内不同的数的个数了很轻而易举了,但是很明显还减去那些不在y1~y2之间的数,首先我们想到的就是直接暴力,对于l~r之间的点遍历,看他们是否在y1~y2这个区间里头,进行处理。没错没错,那肯定T了,所以作为一个有志向的Tlemer,我们要学会一些巧妙的算法,比如说树状数组,用树状数组来维护这个y坐标范围,getsum(y2)-getsum(y1-1)即是我们想要得到的答案

注意:

因为在树状数组里头都是以0作为退出while循环的判断数,所以对于y坐标而言,不能出现0的坐标,所以我们可以考虑将所有的y坐标+1.这样相对而言是没有变化的。

代码:

#include<bits/stdc++.h>

using namespace std;
const int maxn = 2e6 + 5;
#define INF 0x3f3f3f3f
int block[maxn], cnt[maxn], a[maxn], c[maxn], res[maxn];
int t, n, m, s, l, r, num, unit;
int lowbit(int x) {
return x & (-x);
} void updata(int i, int k) {
while (i <= n) {
c[i] += k;
i += lowbit(i);
}
} int getsum(int i) {
int res = 0;
while (i > 0) {
res += c[i];
i -= lowbit(i);
}
return res;
} void add(int x) {
if (!cnt[a[x]]) updata(a[x], 1);//用y坐标更新维护
cnt[a[x]]++;
} void del(int x) {
cnt[a[x]]--;
if (!cnt[a[x]]) updata(a[x], -1);
} struct query {
int l, r, n, ans, yl, yr;
} Q[maxn]; int cmp1(query a, query b) {
return (block[a.l] ^ block[b.l]) ? block[a.l] < block[b.l] : ((block[a.l] & 1) ? a.r < b.r : a.r > b.r);
}//更快,对于左端点在同一奇数块的区间,右端点按升序排列,反之降序。 int main() {
scanf("%d", &t);
while (t--) {
l = 1, r = 0;
scanf("%d%d", &n, &m);
s = sqrt(n);
unit = n / sqrt(m);
memset(cnt, 0, sizeof(cnt));
memset(c, 0, sizeof(c));
num = ceil((double) n / s);
for (int i = 1; i <= num; i++) {
for (int j = (i - 1) * s + 1; j <= s * num; j++)block[j] = i;
}
for (int i = 1; i <= n; i++)scanf("%d", &a[i]), a[i]++;//注:y坐标都加1是为了使y=0的情况不出现,因为y等于0的时候无法进行循环
for (int i = 1; i <= m; i++) {
scanf("%d%d%d%d", &Q[i].l, &Q[i].yl, &Q[i].r, &Q[i].yr);
Q[i].n = i;
Q[i].yl++, Q[i].yr++;
}
sort(Q + 1, Q + m + 1, cmp1);
for (int i = 1; i <= m; i++) {
while (l < Q[i].l)del(l++);
while (l > Q[i].l)add(--l);
while (r > Q[i].r)del(r--);
while (r < Q[i].r)add(++r);
res[Q[i].n] = getsum(Q[i].yr) - getsum(Q[i].yl - 1);
}
for (int i = 1; i <= m; i++)printf("%d\n", res[i]);
}
return 0;
}

1011 Necklace of Beads(待)

题意:

题解:

注意:

代码:

2021“MINIEYE杯”中国大学生算法设计超级联赛(1)的更多相关文章

  1. 2021“MINIEYE杯”中国大学生算法设计超级联赛(8)(1002,1004,1006,1009)

    前言 依旧是白嫖账号,只打了一些题/kk 正题 1002 Buying Snacks 题目大意 \(n\)个物品,每个可以买一次也可以不买,如果买需要选择\(1/2\)块钱的,然后也可以相邻两个一起买 ...

  2. 2021“MINIEYE杯”中国大学生算法设计超级联赛(7)部分题解

    前言 找大佬嫖到个号来划水打比赛了,有的题没写或者不是我写的就不放了. 目前只有:1004,1005,1007,1008,1011 正题 题目链接:https://acm.hdu.edu.cn/con ...

  3. 2022“杭电杯”中国大学生算法设计超级联赛(6)- 1011 Find different

    2022"杭电杯"中国大学生算法设计超级联赛(6)- 1011 Find different 比赛时队友开摆,还剩半个小时,怎么办?? 当然是一起摆 Solution 看到这个题没 ...

  4. 3I工作室的成员在2013年(第6届)中国大学生计算机设计大赛总决赛中荣获全国二等奖

    在暑假举行的2013年(第6届)中国大学生计算机设计大赛中,我院的参赛作品<毕业生论文选导系统>(作者:祝丽艳/许明涛:指导老师:元昌安/彭昱忠)入围总决赛,并荣获全国二等奖. 2013年 ...

  5. "巴卡斯杯" 中国大学生程序设计竞赛 - 女生专场

    Combine String #include<cstdio> #include<cstring> #include<iostream> #include<a ...

  6. hdu_5705_Clock("巴卡斯杯" 中国大学生程序设计竞赛 - 女生专场)

    题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=5705 题意:给你一个时间和一个角度,问你下一个时针和分针形成给出的角度是什么时候 题解:我们可以将这个 ...

  7. hdu_5707_Combine String("巴卡斯杯" 中国大学生程序设计竞赛 - 女生专场)

    题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=5707 题意:给你三个字符串 a,b,c,问你 c能否拆成a,b,a,b串的每一个字符在c中不能变 题解 ...

  8. 2017年“嘉杰信息杯” 中国大学生程序设计竞赛全国邀请赛 Highway

    Highway Accepted : 122   Submit : 393 Time Limit : 4000 MS   Memory Limit : 65536 KB Highway In ICPC ...

  9. 2017年全国大学生物联网设计竞赛(TI杯)华东分赛区决赛总结

    全国大学生物联网设计竞赛(TI杯)是由教育部高等学校计算机类教学指导委员会主办.上海交通大学电子信息与电气工程学院承办.德州仪器半导体技术公司(TI)协办的赛事,自2014年设立以来,一直是物联网领域 ...

  10. HDU 5943 Kingdom of Obsession 【二分图匹配 匈牙利算法】 (2016年中国大学生程序设计竞赛(杭州))

    Kingdom of Obsession Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Oth ...

随机推荐

  1. 生产环境ES的一个持续转换(continuous transform)报错,问题排查

    背景:有一天突然发现,业务统计的一个数据异常,遂立即排查原因,查看后发现一个mode是continuous 的transform是stop状态:日志如下 报错时间:2023-03-26 14:05:2 ...

  2. Dockerfile 时区设置(MacOs有效)

    # 设置时区RUN ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtimeRUN echo 'Asia/Shanghai' >/etc/t ...

  3. 一款超酷、功能强大的一体化网站测试工具:Web-Check

    今天给大家一款网站一体化测试工具:Web-Check! Web-Check 是一款功能强大的一体化工具,用于发现网站/主机的相关信息.用于检查网页的工具,用于确保网页的正确性和可访问性.它可以帮助开发 ...

  4. KingbaseES 的oracle兼容性参数

    KingbaseES用户可通过设置相关的数据库兼容参数,部分或全部启用Oracle兼容特性. 常用的兼容性参数有以下这些: 参数名称 参数说明 ora_forbid_func_polymorphism ...

  5. Scala 特质自身类型

    1 package chapter06 2 3 object Test16_TraitSelfType { 4 def main(args: Array[String]): Unit = { 5 va ...

  6. DNS的各种记录类型的应用解析

    可能很多人平时工作中不会遇到DNS配置相关的问题, 但如果偶尔遇到不同类型DNS记录的配置, 在没有搞清楚它们都是干啥的情况下, 会眼花缭乱, 还记得很多年前实验室配置DNS不太对导致只能访问www. ...

  7. #主席树,Dijkstra,哈希#CF464E The Classic Problem

    题目 边权均为2的幂次的无向图,求 \(S\) 到 \(T\) 的最短路 \(n,m\leq 10^5\) 分析 最短路直接考虑用 Dijkstra,它需要维护松弛操作和堆, 那么也就是要重载加号和小 ...

  8. #RMQ,动态开点线段树#CF803G Periodic RMQ Problem

    题目 给定\(n\)个数,将这个数列复制\(k\)次得到数列\(a\), 对\(a\)满足区间赋值操作和区间最小值询问 \(n\leq 10^5,q\leq 10^5,k\leq 10^4即|a|\l ...

  9. #分治#JZOJ 4211 送你一颗圣诞树

    题目 有\(m+1\)棵树分别为\(T_{0\sim m}\),一开始只有\(T_0\)有一个点,编号为0. 对于每棵树\(T_i\)由T_{a_i}\(的第\)c_i\(个点与\)T_{b_i}\( ...

  10. 微服务集成Spring Cloud Zipkin实现链路追踪并集成Dubbo

    1.什么是ZipKin Zipkin 是一个根据 Google 发表的论文" Dapper" 进行开源实现的分布式跟踪系统. Dapper是Google 公司内部的分布式追踪系统, ...