NOIP模拟22「d·e·f」
T1:d
枚举。
现在都不敢随便打枚举了。
实际上我们只关注最后留下的矩阵中最小的长与宽即可。
所以我们将所有矩阵按a的降序排列。
从第\(n-m\)个开始枚举。
因为你最多拿走\(m\)个。
考虑到交面积是越交越小的,所以我们尽可能的多拿矩阵走。
我们将前\(n-m\)个矩阵丢进堆里,按b排序,小根堆。
我们只关心b第\(n-m\)大的矩阵,因为我们已经决定要刘m个了,原因已经说过了。
所以我们要让堆顶尽可能大。并维护堆的大小为\(n-m\)即可。具体实现见代码。
1A代码。。我爱战神。。。。
#include<bits/stdc++.h>
using namespace std;
namespace STD
{
#define ll long long
#define rr register
#define inf INT_MAX
const int N=1e5+4;
int n,m,t;
struct mat
{
ll a,b;
bool operator<(const mat b_) const
{
return a>b_.a;
}
mat(){}
mat(int a_,int b_){a=a_,b=b_;}
}x[N];
int read()
{
rr int x_read=0,y_read=1;
rr char c_read=getchar();
while(c_read<'0'||c_read>'9')
{
if(c_read=='-') y_read=-1;
c_read=getchar();
}
while(c_read<='9'&&c_read>='0')
{
x_read=(x_read*10)+(c_read^48);
c_read=getchar();
}
return x_read*y_read;
}
class Heap
{
private:
int tot;
mat heap[N<<2];
void push_up(int x)
{
while(x>1)
{
if(heap[x].b<heap[x>>1].b)
{
swap(heap[x],heap[x>>1]);
x>>=1;
}
else break;
}
}
void push_down(int x)
{
int s=x<<1;
while(s<=tot)
{
if(s<tot&&heap[s].b>heap[s+1].b) s++;
if(heap[s].b<heap[x].b)
{
swap(heap[x],heap[s]);
x=s,s=x<<1;
}
else break;
}
}
public:
Heap(){tot=0;}
void reset()
{
for(rr int i=1;i<=tot;i++)
heap[i]=mat(0,0);
tot=0;
}
void insert(mat x)
{
heap[++tot]=x;
push_up(tot);
}
mat top(){return heap[1];}
void pop()
{
heap[1]=heap[tot--];
push_down(1);
}
void remove(int x)
{
heap[x]=heap[tot--];
push_up(x);
push_down(x);
}
int size(){return tot;}
}heap;
};
using namespace STD;
int main()
{
t=read();
while(t--)
{
n=read(),m=read();
for(rr int i=1;i<=n;i++)
x[i].a=read(),x[i].b=read();
sort(x+1,x+1+n);
for(rr int i=1;i<=n-m;i++)
heap.insert(x[i]);
ll ans=-inf;
ans=max(ans,heap.top().b*x[n-m].a);
for(rr int i=n-m+1;i<=n;i++)
{
if(x[i].b>heap.top().b)
{
heap.pop();
heap.insert(x[i]);
}
ans=max(ans,x[i].a*heap.top().b);
}
printf("%lld\n",ans);
heap.reset();
}
}
战神跟我讲的只关心最后留谁这个思想我考试想到了。但当时只是骗分,用这个思想打了个状压就走了。没细想。
这道题写的骗分都对了,开心。QWQ
T2:e
考试时想出了这个联通块其实就是从\(LCA\)到各个点,打了个树剖就走了,暴力跳得父亲。
本机跑进了1s,用的90000多的数据,还挺开心,以为稳了。结果\(T\)了,笑死。
正解是还要打一个主席树,以节点为版本,记录从自己到根的权值情况。
AC代码:
#include<bits/stdc++.h>
using namespace std;
namespace STD
{
#define ll long long
#define rr register
#define inf INT_MAX
const int N=1e5+6;
int n,q,type,cnt;
int a[N],x[N],a_[N];
int to[N<<1],dire[N<<1],head[N];
inline void add(int f,int t)
{
static int num1=0;
to[++num1]=t;
dire[num1]=head[f];
head[f]=num1;
}
int read()
{
rr int x_read=0,y_read=1;
rr char c_read=getchar();
while(c_read<'0'||c_read>'9')
{
if(c_read=='-') y_read=-1;
c_read=getchar();
}
while(c_read<='9'&&c_read>='0')
{
x_read=(x_read*10)+(c_read^48);
c_read=getchar();
}
return x_read*y_read;
}
int fa[N],son[N],top[N],size[N],depth[N];
void dfs1(int x)
{
size[x]=1;
for(rr int i=head[x];i;i=dire[i])
{
if(to[i]==fa[x]) continue;
fa[to[i]]=x;
depth[to[i]]=depth[x]+1;
dfs1(to[i]);
size[x]+=size[to[i]];
if(size[to[i]]>size[son[x]]) son[x]=to[i];
}
}
void dfs2(int x)
{
if(x==son[fa[x]]) top[x]=top[fa[x]];
else top[x]=x;
for(rr int i=head[x];i;i=dire[i])
{
if(to[i]==fa[x]) continue;
dfs2(to[i]);
}
}
int LCA(int x,int y)
{
while(top[x]!=top[y])
{
if(depth[top[x]]>depth[top[y]])
x=fa[top[x]];
else y=fa[top[y]];
}
return depth[x]<depth[y]?x:y;
}
class Pst
{
private:
int tot;
int root[N];
int lc[(N<<1)+N*20];
int rc[(N<<1)+N*20];
int sum[(N<<1)+N*20];
void Insert(int before,int &now,int l,int r,int val);
void Build(int &now,int l,int r);
int query_sum(int before,int now,int l,int r,int st,int en);
int query_rank(int before,int now,int l,int r,int rank);
public:
void build(){Build(root[0],1,n+2);}
void insert(int fa,int son,int val){Insert(root[fa],root[son],1,n+2,val);}
int prev(int fa,int son,int val)
{
int rank=query_sum(root[fa],root[son],1,n+2,1,val);
return query_rank(root[fa],root[son],1,n+2,rank);
}
int succ(int fa,int son,int val)
{
int rank=query_sum(root[fa],root[son],1,n+2,1,val);
return query_rank(root[fa],root[son],1,n+2,rank+1);
}
}t;
void Pst::Build(int &now,int l,int r)
{
now=++tot;
if(l==r) return;
int mid=(l+r)>>1;
Build(lc[now],l,mid),Build(rc[now],mid+1,r);
}
void Pst::Insert(int before,int &now,int l,int r,int val)
{
now=++tot;
sum[now]=sum[before];
if(l==r){sum[now]++;return;}
int mid=(l+r)>>1;
if(val<=mid)
{
rc[now]=rc[before];
Insert(lc[before],lc[now],l,mid,val);
}
else
{
lc[now]=lc[before];
Insert(rc[before],rc[now],mid+1,r,val);
}
sum[now]=sum[lc[now]]+sum[rc[now]];
}
int Pst::query_sum(int before,int now,int l,int r,int st,int en)
{
if(st<=l&&r<=en) return sum[now]-sum[before];
int mid=(l+r)>>1;
int ret=0;
if(st<=mid) ret+=query_sum(lc[before],lc[now],l,mid,st,en);
if(mid<en) ret+=query_sum(rc[before],rc[now],mid+1,r,st,en);
return ret;
}
int Pst::query_rank(int before,int now,int l,int r,int rank)
{
if(l==r)
{
if(sum[now]-sum[before])
return l;
return inf;
}
int mid=(l+r)>>1;
int num=(sum[lc[now]]-sum[lc[before]]);
if(num>=rank)
return query_rank(lc[before],lc[now],l,mid,rank);
return query_rank(rc[before],rc[now],mid+1,r,rank-num);
}
void dfs3(int x)
{
t.insert(fa[x],x,a[x]);
for(rr int i=head[x];i;i=dire[i])
{
if(to[i]==fa[x]) continue;
dfs3(to[i]);
}
}
int find(int x)
{
int l=1,r=cnt;
while(l<r)
{
int mid=(l+r+1)>>1;
if(a_[mid]<=x) l=mid;
else r=mid-1;
}
return l;
}
};
using namespace STD;
int main()
{
n=read(),q=read(),type=read();
for(rr int i=1;i<=n;i++) a[i]=a_[i]=read();
for(rr int i=1;i<n;i++)
{
int u=read(),v=read();
add(u,v),add(v,u);
}
sort(a_+1,a_+1+n);
cnt=unique(a_+1,a_+1+n)-a_-1;
for(rr int i=1;i<=n;i++)
a[i]=lower_bound(a_+1,a_+1+cnt,a[i])-a_;
t.build();
dfs1(1);
dfs2(1);
dfs3(1);
int lastans=0;
while(q--)
{
int r=read(),k=read();
for(rr int i=1;i<=k;i++)
{
x[i]=read();
x[i]=(x[i]-1+lastans*type)%n+1;
}
int lca=x[1];
int r_=find(r);
for(rr int i=2;i<=k;i++)
lca=LCA(lca,x[i]);
int ans=inf;
for(rr int i=1;i<=k;i++)
{
int prev=t.prev(fa[lca],x[i],r_);
int succ=t.succ(fa[lca],x[i],r_);
if(prev!=inf)
ans=min(ans,abs(a_[prev]-r));
if(succ!=inf)
ans=min(ans,abs(a_[succ]-r));
}
lastans=ans;
printf("%d\n",ans);
for(rr int i=1;i<=k;i++)
x[i]=0;
}
}
这道题还涉及到了主席树加减,我直接懵逼了。。。。。。
跑回去学了一下,A了道板子题。
改题时二分写错了,改了半天,这道题细节蛮多的,下面我会提到我改题时碰到的几个细节。
1.二分,我原本用的lower_bound,STL库里的。他的返回值是“在保证有序性的情况下这个数据应该被插在哪”
我为什么会提到这个呢??因为我一开始给r离散化,用的这个,但他的返回是大于或等于r的值得位置,我主席树里是要用小于或等于r的值的位置。所以WA了
后来改为手写,用的李煜东的那本书(算法竞赛进阶指南)上给的算法,才过的。
要看着本书的要注意,打二分一定严格按照标程,他给出的两种二分写法是严格与求前趋后继向配套的,是不可混用的我混用了,然后调了半天FWF。。。
2.联通块是包括lca的,所以在查前趋后继时要用fa[lca]与x[i]的版本,而不是lca与x[i]的版本。
3.主席树查前趋后继的时候要注意处理没有前趋后继的情况。
大概就这些吧。
T3:f
还在调,先鸽掉。
NOIP模拟22「d·e·f」的更多相关文章
- NOIP模拟21:「Median·Game·Park」
T1:Median 线性筛+桶+随机化(??什么鬼?). 首先,题解一句话秀到了我: 考虑输入如此诡异,其实可以看作随机数据 随机数据?? 这就意味着分布均匀.. 又考虑到w< ...
- noip模拟22[d·e·f]
noip模拟22 solutions 哈哈哈,这次暴力打满直接190,其实不到哈哈哈,187.. 这次的题暴力极其好打,但是正解确实不简单... 打了好久才改完这个题,改完的时候爽暴了 这些一个字母的 ...
- csp-s模拟测试44「D·E·F」
用心出题,用脚造数据 乱搞场 1 #include<bits/stdc++.h> 2 #define re register 3 #define int long long 4 #defi ...
- [考试总结]noip模拟22
又发现模拟 \(22\) 的总结也咕掉了,现在补上它... 似乎又是gg的一场. 以为自己的部分分数打的很全,然而到后面发现自己的树剖打假了 \(\color{green}{\huge{\text{树 ...
- NOIP模拟测试「简单的区间·简单的玄学·简单的填数·简单的序列」
简单的区间 $update$ 终于$AC$了 找到$(sum[r]+sum[l](sum表示以中间点为基准的sum)-mx)\%k==0$的点 注意这里$sum$表示是以$mid$为基准点,(即$su ...
- NOIP 模拟 $22\; \rm f$
题解 \(by\;zj\varphi\) 对于一个数,如果它二进制下第 \(i\) 位为 \(1\),那么 \(\rm x\) 在这一位选 \(1\) 的贡献就是和它不同的最高为为 \(i\) 的数的 ...
- NOIP模拟13「工业题·卡常题·玄学题」
T1:工业题 基本思路 这题有一个重要的小转化: 我们将原来的函数看作一个矩阵,\(f(i,j-1)*a\)相当于从\(j-1\)向右走一步并贡献a,\(f(i-1,j)*b\)相当于从\(i-1 ...
- NOIP模拟16:「Star Way To Heaven·God Knows·Loost My Music」
T1:Star Way To Heaven 基本思路: 最小生成树. 假如我们将上边界与下边界看作一个点,然后从上边界经过星星向下边界连边,会发现,他会形成一条线将整个矩形分为左右两个部分. ...
- NOIP模拟26「神炎皇·降雷皇·幻魔皇」
T1:神炎皇 又是数学题,气死,根本不会. 首先考虑式子\(a+b=ab\),我们取\(a\)与\(b\)的\(gcd\):\(d\),那么式子就可以改写成: \[(a'+b')*d=a'b' ...
随机推荐
- PHP5.6.6上运行 ecshop 2.7.3常见问题处理
ecshop在在PHP5.6.6版本以后,有了很多细微的变化.而ECSHOP官方更新又太慢,发现这些问题后也不及时升级,导致用户安装使用过程中错误百出. 整理一下我遇到的问题希望对你们能有些帮组也为了 ...
- Moonraker靶机
仅供个人娱乐 靶机搭建与下载 Monraker靶机ip: 192.168.181.135 kali攻击者ip : 192.168.181.128 说明:获取目标主机的root权限并读取目录中的flag ...
- 创建一个计算器的函数calc含有两个数字,调用函数的函数传递一个函数,分别是实现加减乘除
function calc(num){ var n1=8; var n2=2; num(n1,n2); } //加 functiong jia(a,b){ console.log( a+b ); } ...
- Linux下的Vim文本编辑器(入门)
引言 vim filename:打开名为filename的文件,如果不存在就会创建一个filename文件 Vim的三种使用模式 1. 命令模式 启动Vim时,就进入了命令模式 在该模式下: i:切换 ...
- 【Python机器学习实战】感知机和支持向量机学习笔记(三)之SVM的实现
前面已经对感知机和SVM进行了简要的概述,本节是SVM算法的实现过程用于辅助理解SVM算法的具体内容,然后借助sklearn对SVM工具包进行实现. SVM算法的核心是SMO算法的实现,首先对SMO算 ...
- jmeter之JDBC类组件
~什么是JDBC?:全称名为Java DataBase Connectivity,(java数据库连接),在jmeter中是一种可以远程操作数据库的一类组件. ~jmeter如何操作数据库?:jmet ...
- DVWA(三):SQL injection 全等级SQL注入
(本文不定期更新) 一.所需环境: 1.DVWA 2.web环境 phpstudy/wamp 3.burp suite 二.SQL注入产生的原因: 程序员在编写代码的时候,没有对用户输入数据的合法性进 ...
- S3C2440—8.读写SDRAM
文章目录 一.内部结构 二.相关寄存器 BWSCON BANKCON6 REFRESH BANKSIZE MRSR 三.读写SDRAM SDRAM:Synchronous Dynamic Random ...
- 一个系列搞懂YARN(1)——Yarn架构
前言 几天前和大哥说起了Yarn,大哥问我,你知道Yarn里面怎么进行资源的动态分配回收的吗?我和诚实,说不知道,然后就有了这个系列博文.不同版本的hadoop版本对应的yarn文档会有差别,本文中选 ...
- Java Slf4j日志配置输出到文件中
1.概述 新项目需要增加日志需求,所以网上找了下日志配置,需求是将日志保存到指定文件中.网上找了下文章,发现没有特别完整的文章,下面自己整理下. 1.Java日志概述 对于一个应用程序来说日志记录是必 ...