T1

以下的LIS代指最长不降子序列。

考场看到取模,便想到了之前写过的Medain,取模操作让序列分布均匀,对应到本题上,既然是求LIS,那它应该是有循环节的,后来打表证实确实是有。

然后,我码了个BIT优化LIS。觉得应该能拿30pts,然后就傻逼的跳了,其实正解已经想的差不多了,但是本着先把暴力分都拿到的原则,就跳了 我是sb

考场想法:

既然有循环节,那么就只需要把整个序列拆成三部分分别为A,B,C,其中A为包含一个循环节的最短的那一段序列,B全是循环的,C是最后那一段不完全的循环节,如果有的话。

那么就只需要对A求一下LIS,并记录最优答案是从那个位置转移过来的,多个的话全都记,然后看B中有多少个循环节,就对答案产生多少贡献,最后再对记录下来的求一遍LIS,然后对应到C上,看能拿多少。

看似正确,然而我没细想,假了,或者说我的打法假了,比如下面这组数据:

12

134 33 107 69 41

生成序列为:

134 32 16 20 34 35 0 28 32 16 20 34

很显然,LIS长度为5,但我的会输出4,因为它在A中求了个4,选的是 16,20,34,35,导致在C中选不了,但显然,最优应该是在A中选16,20,28,然后在C中32,34,LIS长度为5。

然而考试的时候也没调出来,30pts的也没交上,只能说是活该吧

正解:

就是找循环节,然后一顿乱搞,把循环节接150遍,其他的贡献都是1。

我的那份调了半个下午没调出来,所以换了做法

pdf上的矩阵快速幂不会,也懒的粘了,就这样吧。

Code
#include<cstdio>
#define MAX 1000010
#define re register
namespace OMA
{
long long n,ans;
int t,a,b,c,d,m,len,xam;
int tmp[MAX],pos[MAX];
inline int max(int a,int b)
{ return a>b?a:b; }
class BIT
{
private:
int tree[MAX];
inline int lowbit(int x)
{ return x&-x; }
public:
inline void insert(int x,int lis)
{
for(re int i=x; i<=xam; i+=lowbit(i))
{ tree[i] = max(tree[i],lis); }
}
inline int query(int x)
{
int res = 0;
for(re int i=x; i; i-=lowbit(i))
{ res = max(res,tree[i]); }
return res;
}
}BIT;
signed main()
{
scanf("%lld%d%d%d%d%d",&n,&t,&a,&b,&c,&d);
if(n==1)
{ printf("1\n"); return 0; }
tmp[1] = t;
for(re int i=2; i<=n; i++)
{
xam = max(xam,tmp[i] = (a*tmp[i-1]*tmp[i-1]+b*tmp[i-1]+c)%d);
if(pos[tmp[i]])
{ len = i-pos[tmp[i]],m = i-1; break ; }
pos[tmp[i]] = i;
}
xam += 1;
ans = (n-m)/len-150,n = (n-m)%len+len*150+m;
for(re int i=m+1; i<=n; i++)
{ tmp[i] = tmp[pos[tmp[m+1]]+i-m-1]; }
int lis = 0;
for(re int i=1; i<=n; i++)
{
tmp[i] += 1;
int res = BIT.query(tmp[i])+1;
BIT.insert(tmp[i],res);
lis = max(lis,res);
}
printf("%lld\n",ans+lis);
return 0;
}
}
signed main()
{ return OMA::main(); }

算了,还是贴一下,虽然没有意义

矩阵快速幂解法

T2

一看就不太可做,留在了最后,瞎打了个背包就没看了,然后接着去调T1了。

别人的想法:

同余最短路,能拿90pts,但好像是假的,然而这玩意我都听都没听过,更别提考场写出来

正解:

%%%沈学长。

是个dp,还没写出来,所以先咕了。

dp实质上是在一个图上跑,平常的dp都是有拓扑序,所以可以直接for循环来转移,想这种出现环的,需要跑个最短路来转移。

Code
咕咕咕

T3

考场直接树剖+线段树,然后打着打着发现思路卡壳了,没继续往下想,因为T1自己的想法还没打,所以干脆拿树剖求了个LCA,丢了个暴力就跑回T1了。

正解:

就是个线段树。

首先不难发现,一个节点 \(u\) 的权值,只有可能对自己的子树产生贡献,所以当一个节点 \(u\) 被修改之后,先用 \(u\) 的权值去更新 \(u\) 的子树,然后去暴力跳 \(u\) 的爹 \(fa\) ,那么\(fa\) 的子树中,除去 \(u\) 的子树那一部分都可以用 \(fa\) 的权值去更新,如果 \(fa\) 的子树在修改前就已经有黑点的话,就说明 \(fa\) 的父亲们或者说祖先之前肯定更新过了子树,就不再接着跳了。

说白了就是区间修改+单点查询

Code
#include<cstdio>
#include<cstring>
#include<climits>
#define MAX 100010
#define re register
#define INF INT_MIN
int n,m;
int w[MAX];
bool vis[MAX];
struct graph
{
int next;
int to;
}edge[MAX<<1];
int cnt=1,head[MAX];
inline void add(int u,int v)
{ edge[++cnt] = (graph){head[u],v},head[u] = cnt; }
namespace FTC
{
int fa[MAX],size[MAX],dfn[MAX];
inline void dfs(int u,int fat)
{
size[u] = 1,dfn[u] = ++cnt,fa[u] = fat;
for(re int i=head[u],v; i; i=edge[i].next)
{
v = edge[i].to;
if(v!=fat)
{ dfs(v,u); size[u] += size[v]; }
}
}
}using namespace FTC;
namespace OMA
{
inline int max(int a,int b)
{ return a>b?a:b; }
class Segment_Tree
{
private:
struct TREE
{
int xam;
int l,r;
int tag;
TREE()
{ xam = -1; }
}st[MAX<<2];
inline int ls(int p)
{ return p<<1; }
inline int rs(int p)
{ return p<<1|1; }
inline void Push_up(int p)
{ st[p].xam = max(st[ls(p)].xam,st[rs(p)].xam); }
inline void Push_down(int p)
{
if(st[p].tag)
{
st[ls(p)].xam = max(st[ls(p)].xam,st[p].tag);
st[ls(p)].tag = max(st[ls(p)].tag,st[p].tag);
st[rs(p)].xam = max(st[rs(p)].xam,st[p].tag);
st[rs(p)].tag = max(st[rs(p)].tag,st[p].tag);
st[p].tag = 0;
}
}
public:
inline void build(int p,int l,int r)
{
st[p].l = l,st[p].r = r;
if(l==r)
{ return ; }
int mid = (l+r)>>1;
build(ls(p),l,mid),build(rs(p),mid+1,r);
}
inline void update(int p,int l,int r,int val)
{
if(l>r)
{ return ; }
if(l<=st[p].l&&st[p].r<=r)
{ st[p].xam = max(st[p].xam,val); st[p].tag = max(st[p].tag,val); return ; }
Push_down(p);
int mid = (st[p].l+st[p].r)>>1;
if(l<=mid)
{ update(ls(p),l,r,val); }
if(r>mid)
{ update(rs(p),l,r,val); }
Push_up(p);
}
inline int query(int p,int pos)
{
if(st[p].l==st[p].r)
{ return st[p].xam; }
Push_down(p);
int ans = INF,mid = (st[p].l+st[p].r)>>1;
if(pos<=mid)
{ ans = max(ans,query(ls(p),pos)); }
else
{ ans = max(ans,query(rs(p),pos)); }
return ans;
}
inline void modify(int u)
{
update(1,dfn[u],dfn[u]+size[u]-1,w[u]);
while(!vis[u]&&fa[u])
{
vis[u] = 1;
update(1,dfn[fa[u]],dfn[u]-1,w[fa[u]]);
update(1,dfn[u]+size[u],dfn[fa[u]]+size[fa[u]]-1,w[fa[u]]);
u = fa[u];
}
}
}Tree;
inline int read()
{
int s=0,w=1; char ch=getchar();
while(ch<'0'||ch>'9'){ if(ch=='-')w=-1; ch=getchar(); }
while(ch>='0'&&ch<='9'){ s=s*10+ch-'0'; ch=getchar(); }
return s*w;
}
signed main()
{
n = read(),m = read();
for(re int i=1; i<=n; i++)
{ w[i] = read(); }
for(re int i=1,u,v; i<=n-1; i++)
{ u = read(),v = read(); add(u,v),add(v,u); }
cnt = 0,dfs(1,0);
Tree.build(1,1,n);
for(re int i=1,u; i<=m; i++)
{
char s[10]; scanf("%s",s),u = read();
if(s[0]=='M')
{ Tree.modify(u); }
if(s[0]=='Q')
{ printf("%d\n",Tree.query(1,dfn[u])); }
}
return 0;
}
}
signed main()
{ return OMA::main(); }

反思总结:

打暴力不要占用太长时间,不然留给调试可能是正解的代码的时间会不太够,导致出现问题,打完暴力后,也要先把暴力交上,给自己留条后路。

不要去搞极限操作,指在距离考试结束还有7s交代码,rp不好,就会挂掉,是极大概率挂掉。

有想法就要赶快码出来,不要放到最后。

noip29的更多相关文章

  1. 20210803 noip29

    考场 第一次在 hz 考试.害怕会困,但其实还好 看完题感觉不太难,估计有人 AK. T3 比较套路,没办法枚举黑点就从 LCA 处考虑,在一个点变成黑点时计算其他点和它的 LCA 的贡献,暴力跳父亲 ...

随机推荐

  1. 《PHP安全编程系列》系列分享专栏

    PHP安全编程系列收藏夹收藏了有关PHP安全编程方面的知识,对PHP安全编程提供学习参考 <PHP安全编程系列>已整理成PDF文档,点击可直接下载至本地查阅https://www.webf ...

  2. ADC采集电流相关知识

    1.AD电流采样电路,是把电路中的电流用采样元件转换为电压信号,然后用ADC量化转换为相应的数字信号.需要你在被采集端串联一个采样电阻,然后采集采样电阻两端的电压,这样就可以把电流输出变换为电压输出. ...

  3. python 12篇 mock接口之flask模块

    一.使用pip install flask按照flask模块. import flask,json # 轻量级web开发框架 server = flask.Flask(__name__) @serve ...

  4. adb 记录ADB执行记录

    自动化测试需要获得当前的activity,来判断处于的页面是否正确: hierarchy view经常连不上真机,无法获得activity,所以直接用 adb命令来查看当前运行的 activity就可 ...

  5. C语言:数的保存 原码 反码 补码

    a=6                                     a=-18 a 的原码就是0000 0000 0000 0110        1000 0000 0001 0010 ...

  6. python pandas 读excel类

    import pandas as pd '''特例说明 file1="a20201220.xlsx" sheetname='Sheet1' df=pd.read_excel(fil ...

  7. [刘阳Java]_Spring AOP入门_第7讲

    AOP技术个人认为是能够完善(改善)面向对象编程OOP.为什么这么说,我们得先从AOP的概念说起,然后通过一段简单的例子加以佐证.这样子大家就可以慢慢地了解AOP 1. AOP概念 AOP为Aspec ...

  8. Redis解读(4):Redis中HyperLongLog、布隆过滤器、限流、Geo、及Scan等进阶应用

    Redis中的HyperLogLog 一般我们评估一个网站的访问量,有几个主要的参数: pv,Page View,网页的浏览量 uv,User View,访问的用户 一般来说,pv 或者 uv 的统计 ...

  9. 构建后端第2篇之---springb @ComponentScan注解使用

    张艳涛写于2021-2-8日 构建后端项目的时候遇到一个问题,在zyt-auth项目的依赖定义了@Component类,这个类在项目启动的时候提示没有找到bean Field tokenService ...

  10. 公有组件ShowCodeList实现原理之一一下拉框的实现

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...