noip模拟29[简单的板子题](虽然我不会)
\(noip模拟29\;solutions\)
这次考试给我最大的伤害,让我意识到了差距
这场考试可以说是非常的简单,就是简单到,看两眼,打个表就有结果了
但是呢?我考得非常的完蛋,只有30pts

据说上一届做这题随便切;
考完之后一看,这第一题第三题都有人切了,我就非常的伤心,但是把题都改过来之后
还是很开心,明天一定要好好考,今天的状态非常不好
明天提起精神A掉至少一道题!!!!
\(T1\; 最长不下降子序列\)
确实,乍一看这题还是挺简单的,我说着我树状数组打的非常的熟练,
就个这玩意不是小case??我就开始敲,突然发现,这个数据范围好像炸掉了。。
一不做二不休,打完了觉得应该拿到30分,就交上去了
然而因为第一个数不符合规律我特判了一下,忘记统计它的答案了。。。。。。00000
第一题就这样无奈的爆零了。。。
其实正解就是一个小dp,也就是我前面的算法加了点其他的东西,
你会发现这个模数只有150,这样根据抽屉原理就可以得到,这个序列必然有循环节,且长度小于模数
(我考场上也意识到了这个模数不对劲,可惜就是没有找到规律,下次多想想)
我们发现当这个序列有了循环节,那我们就可以直接去统计每个循环节的贡献了
本题要求的是不下降子序列,所以每个循环节都至少有1的贡献,要是上升就不一定了
当这个序列出现了循环节,我们就可以将这个序列分为三部分,整块的循环节和前后散的
那我们就可以分别去统计贡献,注意这里前面散块的贡献不能只统计这一小块的
因为你不知道跨越了n个循环节之后还会出现什么,所以这个长度要弄成\(\mathcal{O(T^2)}\)
后面的直接统计就好了,你会发现这时候中间剩下的循环节就直接加1就行了
AC_code
#include<bits/stdc++.h>
using namespace std;
#define re register int
#define ll long long
ll n,t,a,b,c,d;
ll zq,s[90005];
ll fro,beh,dp[90005];
ll ans,sum,beg;
ll pos[305];
struct SZSZ{
ll tr[305];
int lb(int x){return x&(-x);}
void ins(int x,ll v){for(re i=x;i<=d+1;i+=lb(i))tr[i]=max(tr[i],v);}
ll query(int x){ll ret=0;for(re i=x;i;i-=lb(i))ret=max(ret,tr[i]);return ret;}
void clear(){memset(tr,0,sizeof(tr));}
}sz;
signed main(){
scanf("%lld%lld%lld%lld%lld%lld",&n,&t,&a,&b,&c,&d);
int now=1;s[1]=t;
while(!pos[s[now]]){
pos[s[now]]=now;now++;
s[now]=(s[now-1]*s[now-1]*a+s[now-1]*b+c)%d;
//cout<<s[now]<<" ";
}
//cout<<endl;
zq=now-pos[s[now]];
beg=now-zq-1;
fro=min(now-zq-1+zq*zq,n);
//cout<<n<<" "<<fro<<" "<<zq<<endl;
for(re i=1;i<=fro;i++){
if(!s[i])s[i]=(s[i-1]*s[i-1]*a+s[i-1]*b+c)%d;
ll tmp=sz.query(s[i]+1)+1;
sz.ins(s[i]+1,tmp);
dp[i]=max(dp[i],tmp);
ans=max(ans,tmp);
//cout<<i<<endl;
//cout<<s[i]<<" "<<ans<<endl;
}
for(re i=1;i<=zq;i++){
dp[i+beg]=dp[i+beg+zq*(zq-1)];
}
//cout<<endl;
//cout<<ans<<endl;
if(fro==n){printf("%lld",ans);return 0;}
sum=(n-fro)/zq;
beh=n-fro-sum*zq;
//cout<<sum<<" "<<beh<<endl;
for(re i=1;i<=zq;i++){
sz.clear();ll mx=0;
for(re j=1;j<=beh;j++){
if(s[i+beg]>s[j+beg])continue;
ll tmp=sz.query(s[j+beg]+1)+1;
sz.ins(s[j+beg]+1,tmp);
mx=max(mx,tmp);
}
ans=max(ans,dp[i+beg]+mx+sum);
}
printf("%lld",ans);
}
\(T2\; 完全背包问题\)
这个的话,我也是直接打了个最最最普通的背包就溜走了
我其实根本就没看出来是个dp,考完沈队一讲,好像是有点明白,这个题的dp是这样的
设\(f[k][i][j]\)表示处理玩前k个物品,用了i个大物品,得到的总体积模上最小的体积为j的最小体积
就是说我们维护不了每一个值,但是我们可以让这个背包的体积模 \(V_0\) (就是所有物品体积中最小的那个)
其实也不需要最小的,任何一个小于L的都可以,因为我们找到最小的话,就可以无限曾加,得到背包的体积
那么转移就分为当前物品是大物品还是小物品就行了,dp好设计,
因为这个物品可以随便加,所以我们直接先把状态转移到当前层,然后层内转移
你发现这个如果是大物品的话,就可以直接循环转移,小物品的话,就有后效性了,
所以这个时候就直接跑最短路就好了,也就是同余最短路。。。
AC_code
#include<bits/stdc++.h>
using namespace std;
#define re register int
#define ll long long
const ll N=55;
const ll M=1e5+5;
const ll K=1e4+5;
const ll inf=0x3f3f3f3f3f3f3f3f;
ll n,m,v[N],w[M],c,l;
ll f[N][40][K],mv=0,mn=inf;
ll s=20001;
struct DIJ{
ll to[M*2],nxt[M*2],head[M],rp;
ll val[M*2];
bool vis[M];
void clear(){
memset(head,0,sizeof(head));rp=1;
memset(vis,false,sizeof(vis));
}
void add_edg(ll x,ll y,ll z){
to[++rp]=y;
val[rp]=z;
nxt[rp]=head[x];
head[x]=rp;
}
struct node{
ll di,id;
node(){}
node(ll x,ll y){
di=x;id=y;
}
bool operator < (node x)const{
return di>x.di;
}
};
ll dis[M];
priority_queue<node> q;
void smw(){
while(!q.empty())q.pop();
q.push(node(0,s));dis[s]=0;
while(!q.empty()){
ll now=q.top().id;
ll dit=q.top().di;q.pop();
if(vis[now])continue;
vis[now]=true;dis[now]=dit;
for(re i=head[now];i;i=nxt[i]){
ll y=to[i];
if(vis[y])continue;
q.push(node(dit+val[i],y));
}
}
}
}dj;
signed main(){
scanf("%lld%lld",&n,&m);
for(re i=1;i<=n;i++){
scanf("%lld",&v[i]);
mn=min(mn,v[i]);
mv=max(mv,v[i]);
}
scanf("%lld%lld",&l,&c);
memset(f,0x3f,sizeof(f));
//if(f[0][0][0]>1e18)cout<<"sb"<<endl;
f[0][0][0]=0;
for(re k=1;k<=n;k++){
if(v[k]>=l){
for(re j=0;j<mn;j++)
f[k][0][j]=f[k-1][0][j];
for(re i=1;i<=c;i++)
for(re j=0;j<mn;j++)
f[k][i][j]=min(f[k-1][i][j],f[k][i-1][(1ll*j+mn*100-v[k]%mn)%mn]+v[k]);
}
else{
for(re i=0;i<=c;i++){
dj.clear();
for(re j=0;j<mn;j++){
dj.add_edg(s,j,f[k-1][i][j]);
dj.add_edg(j,((1ll*j+v[k]%mn)%mn),v[k]);
}
dj.smw();
for(re j=0;j<mn;j++)f[k][i][j]=dj.dis[j];
}
}
}
//cout<<0x3f3f3f3f<<endl;
for(re i=1;i<=m;i++){
scanf("%lld",&w[i]);
bool flag=false;
ll tmp=w[i]%mn;
for(re j=0;j<=c;j++){
if(w[i]>=f[n][j][tmp]){
flag=true;break;
}
//cout<<f[n][j][w[i]%v[0]]<<endl;
}
//if(w[i]>=f[n][c][w[i]%v[0]])flag=true;
if(flag)printf("Yes\n");
else printf("No\n");
}
}
\(T3\;最近公共祖先\)
这个题是考场上最水的一道题了
直接将每个点的答案转化成每个黑点的贡献,直接dfs序一下,然后更新过的就不要更新了
考完试10min就切掉了
AC_code
#include<bits/stdc++.h>
using namespace std;
#define re register int
const int N=1e5+5;
int n,m,w[N];
int to[N*2],nxt[N*2],head[N],rp;
void add_edg(int x,int y){
to[++rp]=y;
nxt[rp]=head[x];
head[x]=rp;
}
bool vis[N];
int fa[N],dep[N];
int siz[N],son[N],top[N];
int dfn[N],dfm[N],idf[N],cnt;
void dfs1(int x){
siz[x]=1;son[x]=0;
dfn[x]=++cnt;
for(re i=head[x];i;i=nxt[i]){
int y=to[i];
if(y==fa[x])continue;
fa[y]=x;dep[y]=dep[x]+1;
dfs1(y);
}
dfm[x]=cnt;
}
struct XDS{
#define ls x<<1
#define rs x<<1|1
int tr[N*4],laz[N*4];
void build(int x,int l,int r){
tr[x]=-1;
if(l==r)return ;
int mid=l+r>>1;
build(ls,l,mid);
build(rs,mid+1,r);
}
void pushdown(int x){
if(!laz[x])return ;
laz[ls]=max(laz[ls],laz[x]);
tr[ls]=laz[ls];
laz[rs]=max(laz[rs],laz[x]);
tr[rs]=laz[rs];
laz[x]=0;
}
void update(int x,int l,int r,int ql,int qr,int v){
if(ql>qr)return ;
if(ql<=l&&r<=qr){
laz[x]=max(laz[x],v);
tr[x]=laz[x];
return ;
}
pushdown(x);
int mid=l+r>>1;
if(ql<=mid)update(ls,l,mid,ql,qr,v);
if(qr>mid)update(rs,mid+1,r,ql,qr,v);
return ;
}
int query(int x,int l,int r,int pos){
if(l==r)return tr[x];
pushdown(x);
int mid=l+r>>1;
if(pos<=mid)return query(ls,l,mid,pos);
else return query(rs,mid+1,r,pos);
}
#undef ls
#undef rs
}xds;
signed main(){
scanf("%d%d",&n,&m);
for(re i=1;i<=n;i++)scanf("%d",&w[i]);
for(re i=1,x,y;i<n;i++){
scanf("%d%d",&x,&y);
add_edg(x,y);add_edg(y,x);
}
xds.build(1,1,n);
dfs1(1);vis[1]=true;
for(re i=1;i<=m;i++){
char ch[10];int x;
scanf("%s%d",ch,&x);
if(ch[0]=='M'){
int u=x;
xds.update(1,1,n,dfn[u],dfm[u],w[u]);
while(!vis[u]){
vis[u]=true;
xds.update(1,1,n,dfn[fa[u]],dfn[u]-1,w[fa[u]]);
xds.update(1,1,n,dfm[u]+1,dfm[fa[u]],w[fa[u]]);
u=fa[u];
}
}
else{
printf("%d\n",xds.query(1,1,n,dfn[x]));
}
}
}
noip模拟29[简单的板子题](虽然我不会)的更多相关文章
- NOIP模拟 29
T1第一眼觉得是网络流 看见4e6条边200次增广我犹豫了 O(n)都过不去的赶脚.. 可是除了网络流板子我还会什么呢 于是交了个智障的EK 还是用dijkstra跑的 居然有50分!$(RP--)$ ...
- noip模拟12[简单的区间·简单的玄学·简单的填数]
noip模拟12 solutions 这次考试靠的还是比较好的,但是还是有不好的地方, 为啥嘞??因为我觉得我排列组合好像白学了诶,文化课都忘记了 正难则反!!!!!!!! 害没关系啦,一共拿到了\( ...
- NOIP 模拟 $29\; \rm 完全背包问题$
题解 \(by\;zj\varphi\) 一道 \(\rm dp\) 题. 现将所有种类从小到大排序,然后判断,若最小的已经大于了 \(\rm l\),那么直接就是一个裸的完全背包,因为选的总数量有限 ...
- Noip模拟29(瞎眼忌) 2021.8.3
T1 最长不下降子序列 在此记录自己的瞎眼... 考场上像一个傻$der$,自己为了防范上升序列和不下降序列的不同特意的造了一组$hack$数据来卡自己:(第一行是序列长度,第二行是序列) 6 1 5 ...
- NOIP模拟:饼干(简单规律推导)
题目描述 小美有一张很大的网格:2 n * 2 n .每次小美会选一个小矩阵 2 x * 2 x , x > 0,小矩阵不能超过网格的边界.然后把右上一半都放上饼干.下图是当 x=1或2 的时候 ...
- NOIP 模拟29 B 侥幸
这次考得好纯属是侥幸,我T3打表试数试了两个小时,没有想打T2的正解(其实是打不出来)所以这个T3A掉纯属是侥幸,以后还是要打正解 (以下博客最好按全选观看,鬼知道为啥这个样子!) 在这里也口胡一下我 ...
- NOIP 模拟 $13\; \text{卡常题}$
题解 一道环套树的最小点覆盖题目,所谓环套树就是有在 \(n\) 个点 \(n\) 条边的无向联通图中存在一个环 我们可以发现其去掉一条环上的边后就是一棵树 那么对于此题,我们把所有 \(x\) 方点 ...
- noip模拟29
这次终于是早上考试了 早上考试手感不错,这次刷新了以前的最高排名- %%%cyh巨佬 \(rk1\) %%%CT巨佬 \(t2\) 90 纵观前几,似乎我 \(t3\) 是最低的-- 总计挂分10分, ...
- 2021.8.3考试总结[NOIP模拟29]
T1 最长不下降子序列 数据范围$1e18$很不妙,但模数$d$只有$150$,考虑从这里突破. 计算的式子是个二次函数,结果只与上一个值有关,而模$d$情况下值最多只有$150$个,就证明序列会出现 ...
随机推荐
- 【模拟7.16】通讯(tarjan缩点加拓扑排序)
这题确实水,纯板子,考试意外出错,只拿了暴力分QAQ tarjan缩点加上拓扑排序,注意这里求最短路径时不能用最小生成树 因为是单向边,不然就可能不是一个联通图了.... 1 #include< ...
- Ubuntu安装ibmmq
一.前言 安装整个ibmmq的过程中,真的气炸了,在网上搜索到的答案千篇一律,一个安装部署文档居然没有链接地址:为了找到这个开发版本的下载地址找了一下午,不容易啊.也提醒了自己写博文还是得有责任心,把 ...
- Java-Lambda相关使用介绍
频繁使用的语句 Lambda又涉及到comparator和comparable区别(Comparable是实现comparable接口,实现后可以使用Collections.sort或Arrays ...
- Hadoop - 彻底解决警告:WARN util.NativeCodeLoader: Unable to load native-hadoop library for your platform...
目录 1 - 在日志配置文件中忽略警告 - 有效 2 - 指定本地库的路径 - 无效 3 - 不使用 Hadoop 本地库 - 无效 4 - 替换 Hadoop 本地库 - 有效 5 - 根据源码,编 ...
- CosId 1.0.0 发布,通用、灵活、高性能的分布式 ID 生成器
CosId 通用.灵活.高性能的分布式 ID 生成器 介绍 CosId 旨在提供通用.灵活.高性能的分布式系统 ID 生成器. 目前提供了俩大类 ID 生成器:SnowflakeId (单机 TPS ...
- ClickHouse学习系列之六【访问权限和账户管理】
背景 在之前写的文章[用户权限管理]里已经介绍了应该如何设置用户密码以及权限控制.但是只是针对修改配置文件的方式来进行用户权限管理,其实ClickHouse也支持基于RBAC(Role-Based A ...
- Java基础篇(JVM)——字节码详解
这是Java基础篇(JVM)的第一篇文章,本来想先说说Java类加载机制的,后来想想,JVM的作用是加载编译器编译好的字节码,并解释成机器码,那么首先应该了解字节码,然后再谈加载字节码的类加载机制似乎 ...
- 22、正则表达式(用于三剑客grep,awk,sed,内容中包含空行)
简单的说就是为处理大量的字符串而定义的一套规则和方法,通过定义特殊符号的辅助,系统管理员就可以快速过滤,替换城输出需要的字符串 : ^:^word 表示匹配以什么字符开头的内容: $:word$表示匹 ...
- 20、高可用数据同步工具drbd介绍
20.1.什么是drbd: 20.2.drbd的工作原理: 20.3.drbd的同步模式: 1.实时同步模式: 2.异步同步模式: 20.4.drbd生产应用场景: 1.生产场景中drbd常用于基于高 ...
- Centos7中安装elasticsearch
第一步:必须要有jre支持 elasticsearch是用Java实现的,跑elasticsearch必须要有jre支持,所以必须先安装jre 第二步:下载elasticsearch 进入官方下载 h ...