NOIP 模拟 七十七
100+60+95+30; T4 一个变量打错挂了40。。
T1 最大或
考虑从高到低枚举的二进制位,然后和的对应二进制位进行比较。如果两
者相同,那么不论怎么选择,,答案在这个位置上的值一定和在这个位置上的
值相同;否则,一定有在这个位置上是1,而在这个位置上是0。那么,我们只
需要选择 = ,而 = (...011...1)2即可,其中前面省略号的部分表示,二进
制表示相同的部分。以此进行答案计算即可。
考试时没有严谨的证明,感觉固定 r 好像是对的,试了好几组数据全部调整了出来,然后就按照这个思路打的。
#include<bits/stdc++.h>
#define int long long
using namespace std;
int T,l,r,lim[61],maxn,need[61],limm[69],zhi[66];
inline void dfs(int x,int lim1,int lim2,int val)
{ maxn=max(maxn,r|val);if(x==-1)return;
int be=0,en=1;if(lim1)en=lim[x];if(lim2)be=limm[x];
if(!lim1 and !lim2){val|=(zhi[x]);maxn=max(maxn,r|val);return;}
for(int i=be;i<=en;++i)dfs(x-1,(lim1 and i==lim[x]),(lim2 and i==limm[x]),i?val|(1ll<<x):val);
}
signed main()
{ freopen("maxor.in","r",stdin);
freopen("maxor.out","w",stdout);
scanf("%lld",&T);
for(int i=0;i<=59;++i)zhi[i]=zhi[i-1]+(1ll<<i);
while(T--)
{ scanf("%lld%lld",&l,&r);
maxn=r;memset(lim,0,sizeof(lim));memset(limm,0,sizeof(limm));
for(int i=59;i>=0;--i)lim[i]=((r&(1ll<<i))!=0),limm[i]=((l&(1ll<<i))!=0);
dfs(60,1,1,0);printf("%lld\n",maxn);
}
}
T2 答题
本道题的实质其实是求用所给的个数组成的2:个数中的第大值。其中 =
(2:×)。
直接枚举显然不能通过,所以我们需要进行折半枚举,即枚举求出前:
3个数可
以组成的所有值,以及后:
3个数可以组成的所有值。二分需要求的第大值是多少,
这样,题目相当于求从前:
3个数组成的所有值以及后:
3个数组成的所有值中各取出
一个数,并且两个数的和大于等于二分值的数对有多少组。对两部分从小到大进
行排序,并按顺序枚举第一部分选择的数,则第二部分中可以选择的数落在第二
部分的一个后缀中,并且随着第一部分的枚举值越来越大,这个后缀也越来越大。
使用指针进行线性扫描即可。
想到了转化为划分 k 大值,也想到了middle,然后就罢工了。。。。今天状态不好,脑子热。。
#include<bits/stdc++.h>
#define int long long
using namespace std;
double p,dd=1;
int a[41],n,siz,sum=0,maxn,w1[(1<<20)+10],w2[(1<<20)+10],U1,U2,tot1,tot2,lim;
inline bool check(int x)
{ int res=0;int zhi=U2;
for(int i=1;i<=U1;++i)
{ while(zhi and w1[i]+w2[zhi]>x)--zhi;
res+=zhi;
}
return res>=lim;
}
signed main()
{ freopen("answer.in","r",stdin);
freopen("answer.out","w",stdout);
scanf("%lld %lf",&n,&p);
for(int i=1;i<=n;++i)scanf("%lld",&a[i]),siz+=a[i];
U1=(1<<n/2);U2=(1<<(n+1)/2);
for(int i=1;i<=n/2;++i)w1[1<<i-1]=a[i];
for(int i=1;i<=(n+1)/2;++i)w2[1<<i-1]=a[i+n/2];
for(int i=1;i<U1;++i)if(!w1[i])w1[i]=w1[i&(-i)]+w1[i^(i&(-i))];
for(int i=1;i<U2;++i)if(!w2[i])w2[i]=w2[i&(-i)]+w2[i^(i&(-i))];
sort(w1+1,w1+1+U1);sort(w2+1,w2+1+U2);
lim=ceil(p*(1ll<<n));
cout<<lim<<endl;
int l=0,r=siz,ans=0;
while(l<=r)
{ int mid=(l+r)>>1;
if(check(mid))ans=mid,r=mid-1;
else l=mid+1;
}
printf("%lld\n",ans);
}
T3 联合权值?改
本题的正解复杂度为(-.M)。
先提出一个结论:在一个有条边的图中,三元环的个数为(-.M)的。显然
一个点数为(N.M)的完全图可以使得三元环个数取到这个上界,但是这是对边
的利用率最高的一种做法,你无法找到一个利用率更高的图。
第一问(求最大值):枚举点,将和它相邻的点按权值从大到小排序。接着
二重循环枚举点对(即枚举点,),每次枚举时,如果可行( − −是(,)
之间的一条最短路)就停止枚举。否则一定是找到了一个三元环(,,)。所以
总的失败枚举数不会超过(-.M)。如果使用哈希来判定是否失败,就可以做到
单次判定失败(1),总复杂度(-.M)。
第二问(求和):枚举点,求出和相邻的点的权值的和的平方,再减去和
相邻的点的权值的平方的和。在没有三元环的情况下,上述操作就可以正确求
出答案。再把三元环纳入考虑,即扣掉因三元环产生的非法联合权值。
考虑按如下方式寻找三元环:对于每个点进行一次预处理,求出和相邻的,
并且点的度数大于,或者点的度数和相同,但点的编号大于的点。接着,枚
举点,再枚举与相邻的满足上述条件的点,再枚举与相邻的满足上述条件
的点,然后使用哈希算法判断(,,)是否构成三元环。如果构成三元环,则我
们可以把该三元环产生的三种联合权值从答案中扣去。我们可以分析一下这么做
的复杂度:枚举点和的总复杂度应该是()的。如果的度数不超过N.M,则
枚举第三个点的时间不超过(N.M);否则的个数应该不超过(N.M)(因为度
数总和是()的,所以度数超过N.M的点数应该是N.M的)。实际上,上述做法
可以直接证明“在一个有条边的图中,三元环的个数为(-.M)的”这一个结论。
综上,本题做法的总复杂度是(-.M)的。
然而暴力可以撵过,由于评测机波动,掉了 5 分。
#include<bits/stdc++.h>
#define int long long
using namespace std;
int n,m,ans2,ans1,t,val[40001];
vector<int>p[40001];
set<int>st[40001];
signed main()
{ freopen("link.in","r",stdin);
freopen("link.out","w",stdout);
scanf("%lld%lld%lld",&n,&m,&t);
for(int i=1;i<=m;++i)
{ int a,b;scanf("%lld%lld",&a,&b);
p[a].push_back(b);p[b].push_back(a);
st[a].insert(b);st[b].insert(a);
}
ans1=-1;
for(int i=1;i<=n;++i)scanf("%lld",&val[i]);
for(int i=1;i<=n;++i)
for(int j=0;j<p[i].size();++j)
for(int k=j+1;k<p[i].size();++k)
{ int u=p[i][j],v=p[i][k];
if(st[u].find(v)!=st[u].end())continue;
ans1=max(ans1,val[u]*val[v]);
ans2+=val[u]*val[v];
}
if(t!=2)cout<<ans1<<endl;
else puts("0");
if(t!=1)cout<<ans2*2<<endl;
else puts("0");
}
T4 主仆见证了 Hobo 的离别
考场暴力建边暴力搜,应该是平方复杂度,预估七十分,然而。。
for(int j=1;j<=k;++j)scanf("%d",&a[k]);
直接干废了。。
真不知道我是怎么打的,状态极差。
正解同样建树,如果无祖先关系,肯定不行。否则就是一路交,另一种是一路并。并查集不会用,用了倍增。
#include<bits/stdc++.h>
using namespace std;
int n,m,tot,a[500001],id[500001],du[500001],zhi,siz[500001],dfn[500001],rt,cnt,f[500001][24],fa[500001][24],dep[500001];
vector<int>p[500001];
queue<int>Q;pair<int,int>t[500001];
bool vis[500001];
inline void dfs(int x,int ff)
{ f[x][0]=id[ff];fa[x][0]=ff;siz[x]=1;dfn[x]=++cnt;dep[x]=dep[ff]+1;
for(int i=1;i<=23;++i)fa[x][i]=fa[fa[x][i-1]][i-1],f[x][i]=f[fa[x][i-1]][i-1]|f[x][i-1];
for(auto i:p[x])if(i!=ff)dfs(i,x),siz[x]+=siz[i];
}
inline int work(int x,int y)
{ if(dfn[x]>=dfn[y] and dfn[x]+siz[x]<=dfn[y]+siz[y])
{ int ii=0;
for(int i=23;i>=0;--i)if(dep[fa[x][i]]>=dep[y])ii|=f[x][i],x=fa[x][i];
return (ii!=3 and ii!=1);
}
if(dfn[x]<=dfn[y] and dfn[x]+siz[x]>=dfn[y]+siz[y])
{ int ii=0;
for(int i=23;i>=0;--i)if(dep[fa[y][i]]>=dep[x])ii|=f[y][i],y=fa[y][i];
return (ii!=2 and ii!=3);
}
return 0;
}
signed main()
{ freopen("friendship.in","r",stdin);
freopen("friendship.out","w",stdout);
scanf("%d%d",&n,&m);
for(int i=1;i<=n;++i)id[i]=i;tot=n;
for(int i=1;i<=m;++i)
{ int opt,op,k,x,y;
scanf("%d",&opt);
if(opt==1)
{scanf("%d%d",&x,&y);t[++zhi]=make_pair(x,y);}
else
{ scanf("%d%d",&op,&k);
for(int j=1;j<=k;++j)scanf("%d",&a[j]);
int ii=id[a[1]];
if(k==1){id[++tot]=0;p[tot].push_back(a[1]);p[a[1]].push_back(tot);du[a[1]]++;continue;}
++tot;
if(op==0)
{ id[tot]=1;
for(int j=1;j<=k;++j)p[tot].push_back(a[j]),p[a[j]].push_back(tot),++du[a[j]];
}
else
{ id[tot]=2;
for(int j=1;j<=k;++j)p[tot].push_back(a[j]),p[a[j]].push_back(tot),++du[a[j]];
}
}
}
rt=tot+1;
for(int i=1;i<=tot;++i)if(!du[i]){p[rt].push_back(i);p[i].push_back(rt);}
dfs(rt,0);
for(int i=1;i<=zhi;++i)printf("%d\n",work(t[i].first,t[i].second));
}
NOIP 模拟 七十七的更多相关文章
- NOIP 模拟 七十一
最后一场多校模拟赛,好像是信心赛??不过考的不行..最近难题比较多,对题目的难度把握不够好,经常出现简单题跳过的现象. 100+100+20+40 T1 签到题(qiandao) 如果一个点的度数不是 ...
- NOIP 模拟七 考试总结
T1匹配 签到大水题,这里有hash,kmp,ac自动机,还有后缀数组,后缀自动机任您挑选. 不过这个数据范围有些坑啊,re就很不爽.做法我还是比较倾向hash的,毕竟不论神魔字符算法,hash大都能 ...
- 「题解」NOIP模拟测试题解乱写I(29-31)
NOIP模拟29(B) T1爬山 简单题,赛时找到了$O(1)$查询的规律于是切了. 从倍增LCA那里借鉴了一点东西:先将a.b抬到同一高度,然后再一起往上爬.所用的步数$×2$就是了. 抬升到同一高 ...
- Nescafe #29 NOIP模拟赛
Nescafe #29 NOIP模拟赛 不知道这种题发出来算不算侵权...毕竟有的题在$bz$上是权限题,但是在$vijos$似乎又有原题...如果这算是侵权的话请联系我,我会尽快删除,谢谢~ 今天开 ...
- 2019.7.29 NOIP模拟测试10 反思总结【T2补全】
这次意外考得不错…但是并没有太多厉害的地方,因为我只是打满了暴力[还没去推T3] 第一题折腾了一个小时,看了看时间先去写第二题了.第二题尝试了半天还是只写了三十分的暴力,然后看到第三题是期望,本能排斥 ...
- NOIP模拟赛20161022
NOIP模拟赛2016-10-22 题目名 东风谷早苗 西行寺幽幽子 琪露诺 上白泽慧音 源文件 robot.cpp/c/pas spring.cpp/c/pas iceroad.cpp/c/pas ...
- contesthunter暑假NOIP模拟赛第一场题解
contesthunter暑假NOIP模拟赛#1题解: 第一题:杯具大派送 水题.枚举A,B的公约数即可. #include <algorithm> #include <cmath& ...
- NOIP模拟赛 by hzwer
2015年10月04日NOIP模拟赛 by hzwer (这是小奇=> 小奇挖矿2(mining) [题目背景] 小奇飞船的钻头开启了无限耐久+精准采集模式!这次它要将原矿运到泛光之源的矿 ...
- 大家AK杯 灰天飞雁NOIP模拟赛题解/数据/标程
数据 http://files.cnblogs.com/htfy/data.zip 简要题解 桌球碰撞 纯模拟,注意一开始就在袋口和v=0的情况.v和坐标可以是小数.为保险起见最好用extended/ ...
随机推荐
- netty系列之:搭建自己的下载文件服务器
目录 简介 文件的content-type 客户端缓存文件 其他HTTP中常用的处理 文件内容展示处理 文件传输进度 总结 简介 上一篇文章我们学习了如何在netty中搭建一个HTTP服务器,讨论了如 ...
- JDK方法区、元空间区别 & String.intern相关面试题
一.方法区.永久代.元空间 1.方法区.永久代 方法区也是各个线程共享的内存区域,它用于存储已经被虚拟机加载的类信息.常量.静态变量.即时编译器编译后的代码等数据.方法区域又被称为"永久代& ...
- Windows下安装Apollo时的几个常见问题
今天在本地安装Apollo时遇到几个问题,觉得还是记录下来,希望能给有需要的朋友提供帮助. 安装的过程参考这篇教程,https://www.jianshu.com/p/6cf4b15ba82f.流程基 ...
- Python常见问题 - python3 requests库提示警告InsecureRequestWarning的问题
当使用 requests 库发送请求时报了以下警告 D:\python3.6\lib\site-packages\urllib3\connectionpool.py:847: InsecureRequ ...
- vue-cli-service build 环境设置
zhidao zhouzongshuo的那个是使用vue-cli3打包项目,通过配置不同的指令给项目设置不一样的配置. npm run serve时会把process.env.NODE_ENV设置为' ...
- ByteArrayOutputStream小测试
import java.io.*; import org.junit.Test; public class ByteArrayOutputStreamTest { @Test public void ...
- angularjs $http.get 和 $http.post 传递参数
$http.get请求数据的格式 $http.get(URL,{ params: { "id":id } }) .success(function(response, status ...
- 数据结构逆向分析-Map
数据结构逆向分析-Map map是一个典型的二叉树结构,准确的来说是一个平衡二叉树或者红黑树,特点是数据存储是有序的存储. 参考侯杰老师的stl源码剖析,map里面采用的是RB-TREE也就是红黑树 ...
- 记一次docker compose的低级错误
记一次docker compose的低级错误 问题 今天在学习dockercompose的时候,启动docker compose up,结果却出现异常 Error response from da ...
- Kubernetes-Pod介绍(四)-Deployment
前言 本篇是Kubernetes第七篇,大家一定要把环境搭建起来,看是解决不了问题的,必须实战. Kubernetes系列文章: Kubernetes介绍 Kubernetes环境搭建 Kuberne ...