首页 > 其他分享 >2024.8.18

2024.8.18

时间:2024-08-18 22:17:20浏览次数:9  
标签:oo 10 leq 2024.8 18 样例 int 毛毛虫


DATE #:20240818

ITEM #:DOC

WEEK #:SUNDAY

DAIL #:捌月拾伍

TAGS
	<iframe border="0" frameborder="no" height="86" marginheight="0" marginwidth="0" src="//music.163.com/outchain/player?type=2&id=494858498&auto=0&height=66" width="330"></iframe>
< BGM = "pure imagination--Rook1e" >
< theme = oi-contest >
< [NULL] >
< [空] > 
< [空] >
``` 前天是小兔子,昨天是小鹿,今天是你。-- Clannad ```

T1 玩具

时间限制: 1 s   内存限制: 512 MB   测评类型: 传统型

题目描述

小T给小L买了一个玩具—毛毛虫。(不要鄙视小T的审美),毛毛虫的构造非常简单,由上下两部分组成:

上半部分是毛毛虫的身体,长度为 \(b\)。

下半部分是毛毛虫的脚,每只脚占一个单位长度,毛毛虫共有 \(L\) 只脚。

一开始毛毛虫的脚在最左边 \(L\) 个位置,身体在最左边 \(b\)个位置,最后毛毛虫的脚要在最右边 L$ 个位置,身体在最右边 \(b\) 个位置。

现在,毛毛虫要从木板的左边爬到右边。木板的长度为 \(n\),由于小T比较穷,用了很多年的木板在某些位置已经破了。毛毛虫不能将脚放在这些破的位置。

众所周知,毛毛虫是通过蠕动爬行的,因此,毛毛虫的运动分为两种操作:

  1. 将某一只脚向右移动若干距离,要求最后的落脚点的木板不能是破的,并且,要严格在前一只脚的左边。
  2. 将上半部分身体向右移动\(1\)个距离,要求移动后所有的脚仍然在身体下方。

这两种的操作均需要花费\(1\)的时间。

现在,小T希望聪明的你告诉他,毛毛虫爬到最右边(即身体的的最右一格在 n\(n\)号位置,并且所有的脚也在最右边)最少需要多少时间。

当然,有的时候,小T家的木板已经残破不堪,毛毛虫无法到达最右边,那么请输出\(“IMPOSSIBLE”\)。

问题保证最开始的 \(L\) 个位置和最后的 \(L\) 个位置木板都是好的。

输入格式

第一行空格隔开的三个数 \(L,b,n\)。

第二行连续 \(n\) 个 \(0/1\),\(0\) 表示当前位置木板是破的,\(1\) 表示当前位置木板完好。

输出格式

一行一个数,表示毛毛虫花费的最少时间。(或者“IMPOSSIBLE”\(“IMPOSSIBLE”\))

样例输入

1 3 5

11011

样例输出

5

数据范围与约定

\(20\%\) 的数据满足 \(n \le 10\)。

对于另外 \(20\%\) 的数据,满足\(L = 1\)。

对于另外 \(15\%\) 的数据,满足没有破的地板。

对于另外 \(25\%\) 的数据,满足 \(n, m \le 10000\)。

\(100\%\) 的数据满足

CODE
    
//2024.8.17
//by white_ice
//#115. 【2020.11.22 NOIP模拟赛 T2】玩具
#include
//#include"need.cpp"
using namespace std;
#define int long long
#define itn long long
constexpr int oo = 3e6+10;
int nl,b,n;char c[oo];int st[oo];
main(void){
    //fre();
    cin.tie(0)->sync_with_stdio(0);
    cin >> nl >> b >> n;
    cin >> c+1;
    for (int i=1;i<=n;++i)
        st[i] = c[i]-'0';
    int r = b;   int l = r-nl+1;
    int cnt = nl; int cnt0 = 0;
    int out = 0;
    for (int i=b;i;--i){
        if (cnt==0){out += nl;break;}
        if (!st[i])--l;
        else --cnt;
    }
    while (r<n){ int="" tmp="l;" while="" (r<n&&r-b+1<tmp){="" ++r;="" ++out;="" if="" (st[r]="=" 1)="" {="" ++l;while="" (st[l]="=" 0){++l;}="" }="" (l<="r-b+1){" puts("impossible");="" return="" 0;="" out+="nl;" cout="" <<="" out="" flush;="" exit(0);="" <="" code="">

直接输出impossible可以获得5分的友情分

但是正解也是非常难崩,直接贪心加模拟即可

每次记录最后一个虫脚出现的位置即可


T2 找朋友

时间限制: 1 s   内存限制: 1024 MB   测评类型: 传统型

题目描述

N 个鱼缸排成一列,按照 \(1, 2, \ldots, N\) 的顺序编号。第 \(i\) 个鱼缸里水的高度为 \(H_i\) ,保证 \(H_i < W\) 。

现在放入 \(M\) 条鱼,第 \(i\) 条鱼被放入第 \(P_i\) 个鱼缸,同时它最多能跳 \(J_i\) 单位。鱼 \(i\) 能从鱼缸 \(a\) 跳到鱼缸 \(b\) 当且仅当 \(|a - b| ≤ 1\) 且 \(J_i > W - H_a\) 。

现在每条鱼开始寻找朋友,他们从一开始所在的鱼缸开始跳,直到跳到某个鱼缸然后停下。等所有鱼都停下了,处在同一鱼缸的鱼就会相互认识。求最后相互认识的鱼的对数的最大值。

输入格式

第一行三个正整数 \(N, M, W\)(\(2 ≤ N ≤ 10^4, 1 ≤ M ≤ 200, 2 ≤ W ≤ 10^6\))。

第二行 \(N\) 个正整数 \(H_1, H_2, \ldots, H_N\)(\(1 ≤ H_i < W\))。

接下来的 \(M\) 行描述每条鱼,其中的第 \(i\) 行有两个正整数 \(P_i, J_i\)(\(1 ≤ P_i ≤ N, 1 ≤ J_i ≤ 10^6\))。

输出格式

一行一个整数表示答案。

样例输入

3 4 5
4 2 3
1 1
3 3
2 3
1 7

样例输出

3

样例说明

鱼 \(1\) 由于 \(J_1 < W - H_1\) 只能留在鱼缸 \(1\) 。

类似地,鱼 \(3\) 只能留在鱼缸 \(2\) 。

令鱼\(4\) 跳到鱼缸 \(2\) ,鱼 \(2\) 跳到鱼缸 \(2\) 。此时鱼 \(2, 3, 4\) 两两认识,对数达到 \(3\) ,可以证明这是最大值。

数据规模与约定

子任务编号 分数 额外限制
1 3 \(H_i\) 全部相同
2 7 \(N, M ≤ 20\)
3 9 \(N, M ≤ 50\)
4 14 \(M ≤ 50\)
5 67

时间限制: $ 1 \text{s}$

空间限制:\(1024 \text{MB}\)

CODE
    
//2024.8.18
//by white_ice
#include
//#include"need.cpp"
using namespace std;
#define itn long long
#define int long long
constexpr int oo = 2000006;
int n,m,w,k;
int h[oo],l[oo],r[oo];
int ned[oo];int f[1003][1003];
int st[oo],sum[oo];
main(void){
    //fre();
    cin.tie(0)->sync_with_stdio(0);
    cin >> n >> m >> w;
    for(int i=1;i<=n;i++)cin >> k,h[i] = w - k;
    for(itn x,y,i=1;i<=m;i++){
        cin >> x >> y;
        l[i] = r[i] = x;
        while (l[i]>1&&y>h[l[i]]) l[i]--;
        while (r[i]<n&&y>h[r[i]]) r[i]++;
        ned[2*i-1] = l[i];ned[2*i] = r[i];
    }
    sort(ned+1,ned+2*m+1);
    int cnt = unique(ned+1,ned+2*m+1)-ned-1;
    for (itn i=1;i<=m;i++)
        l[i] = lower_bound(ned+1,ned+cnt+1,l[i])-ned,
        r[i] = lower_bound(ned+1,ned+cnt+1,r[i])-ned;
    for (int len=1;len<=cnt;len++){
        for (itn i=1;i+len-1<=cnt;i++){
            int j=i+len-1;
            for (itn k=1;k<=m;k++) if(i<=l[k]&&r[k]<=j){sum[l[k]]++;sum[r[k]+1]--;}
            for (itn k=i;k<=j;k++){
                sum[k] += sum[k-1];
                int p = f[i][k-1]+f[k+1][j];
                f[i][j] = max(f[i][j],sum[k]*(sum[k]-1)/2+p);
            }
            for (itn k=i;k<=j+1;k++)sum[k] = 0;
        }
    }
    cout << f[1][cnt] << flush;
    exit(0);
}
	

发现每一条鱼都有一个跳跃区间,

我们只要计算区间中重叠最多的地方即可

预处理出区间,离散化后使用区间DP求解


T3 异或

时间限制: 2 s   内存限制: 1024 MB   测评类型: 传统型

题目描述

给定一个长度为 \(n\) 的非负整数列 \(a_1, a_2, ..., a_n\) 和非负整数 \(x\),

求有多少个非空子序列 \(1 \leq b_{1} < b_{2} < \cdots < b_{k} \leq n\) , 满足对任意的 \((i, j)(1 \leq i < j \leq k)\) 都有 \(a_{b_{i}} \oplus a_{b_{j}} \geq x\)。

其中 \(\oplus\) 表示按位异或。

由于这个数可能非常大,你只需要回答这个数除以 998244353\(998244353\) 的余数即可。

输入格式

第一行两个整数 \(n, x\left(1 \leq n \leq 3 \cdot 10^{5}, 0 \leq x < 2^{60}\right)\) 。

第二行 \(n\) 个整数 \(a_{1}, a_{2}, \ldots, a_{n}\left(0 \leq a_{i} < 2^{60}\right)\) 。

输出格式

一行一个整数,表示满足条件的子序列的个数除以 \(998244353\) 的余数。

样例输入1

3 0
0 1 2

样例输出1

7 

样例输入2

3 2
0 1 2    

样例输出2

5 

样例输入3

3 3
0 1 2

样例输出3

4 

样例输入4

7 4
11 5 5 8 3 1 3

样例输出4

35

样例解释

第一组样例数据中,所有\(2^3 − 1\) 个非空子序列都合法。

第二组样例数据中,除 \([1, 2]\) 和 \([1, 2, 3]\) 外,所有非空子序列都合法。

第三组样例数据中,合法的子序列有 \([1], [2], [3]\) 和\([2, 3]\)。

数据范围

对于 \(10\%\) 的测试点,满足 \(n \leq 20\)。

对于另外 \(20\%\) 的测试点,满足 \(n \leq 5000\)。

对于另外 \(50\%\) 的测试点,满足\(n \leq 10^5\)。

对于 100%\(100\%\) 的测试点,满足 \(1 \leq n \leq 3 \cdot 10^{5}, 0 \leq x < 2^{60}, 0 \leq a_{i} < 2^{60}\)。

CODE
    
//2024.8.18
//by white_ice
//#120. 【2020.11.25 NOIP模拟赛 T3】异或
#include
//#include"need.cpp"
using namespace std;
#define int long long
#define itn long long
constexpr int mod = 998244353;
constexpr int oo = 3e5 + 10;
int n, x;int ned[oo];
int st[oo];int pow2[oo];
int out;
int tot = 1;
int sum[oo*60],ch[oo*60][2];
__inline void insert(int x,int v){
    int u = 1;
    sum[u] += v;
    for (int i=59;~i;i--) {
        if (x>>i&1){if (!ch[u][1])ch[u][1] = ++tot;u = ch[u][1];}
        else {if (!ch[u][0])ch[u][0] = ++tot;u = ch[u][0];}
        sum[u] += v;
    }
}
__inline int query(int v){
    int u = 1;int res = 0;
    for (int i=59;~i;i--) {
        if (x>>i&1)
            u=ch[u][(v>>i&1)^1];
        else {
            res += sum[ch[u][(v>>i&1)^1]];
            res %= mod;
            u = ch[u][v>>i&1];
        }
        if (!u) return res;
    }
    res += sum[u];
    return res;
}
main(void){
    //fre();
    cin.tie(0)->sync_with_stdio(0);
    cin >> n >> x;
    for (int i=1;i<=n;i++)cin >> st[i];
    sort(st+1,st+n+1);
    for (int i=1;i<=n;i++){
        ned[i] = query(st[i])+1;
        insert(st[i],ned[i]);
        out = (out+ned[i])%mod;
    }
    cout << out << flush;
    exit(0);
}
</code>

先引入一个引理:

结论:一个集合中任意两项异或的最小值,一定为排序后相邻两项异或的最小值。

十分简单证明

那么我们就可以在子树上DP了,

转移:

\[f_i=\sum\limits_{j=1}^{i-1}f_j[a_j \oplus a_i \le x]+1 \]

这个扔到trie树上维护即可。


T4 送给好友的礼物

时间限制: 5 s   内存限制: 512 MB   测评类型: 传统型

题目背景

小 M 和小 B 是一对好朋友,她们很喜欢草莓。

题目描述

给定一棵包含 \(n\) 个节点的树 \(T\),节点从 \(1 \sim n\) 顺序编号。

小 M 和小 B 在时刻 \(0\) 都在 \(1\) 号节点。

从时刻 \(1\) 开始的每个时刻初,小 M 和小 B 都可以选择:移动到一个和自己所在节点直接相连的节点,或者停留在当前所在的节点。

树上有 \(k\) 个草莓,它们分布在 \(k\) 个不同的节点上。

小 M 和小 B 想要收集到所有的草莓,任何一个时刻末,如果小 M 或者小 B 在某一个草莓所在的节点上,那么这个草莓就被收集了。

她们不想花费太多的时间,因此你需要回答:至少在第几时刻末,小 M 和小 B 可以收集到所有的草莓,并且都回到节点 \(1\)。

输入格式

第一行两个整数 \(n\) 和 \(k\) \((1 \leq k \leq n \leq 415)\),分别表示树的节点个数和草莓的个数。

接下来 \(n-1\) 行,每行两个整数 \(u\) 和 \(v\) \((1 \leq u,v \leq n)\),表示树上有一条从 \(u\) 到 \(v\) 的边。

接下来一行 \(k\) 个互不相同的整数 \(a_1,a_2 \cdots a_k\),分别表示这 \(k\) 个草莓所在的节点。

输出格式

一行一个整数,所求答案。

输入样例 #1

7 4
1 2
2 3
2 4
1 5
5 6
6 7
3 4 5 7

输出样例 #1

6

输入样例 #2

1 1
1

输出样例 #2

0

样例解释

img

小 M 的路线是:1->2->3->2->4->2->1

小 B 的路线是:1->5->6->7->6->5->1

数据范围

  • Subtask 1 (6 分): \(n \leq 3\)
  • Subtask 2 (1 分): \(k = 1\)
  • Subtask 3 (11 分): \(n \leq 7\)
  • Subtask 4 (17 分):\(k \leq 20\)
  • Subtask 5 (42 分):\(n \leq 90\)
  • Subtask 6 (23 分):无特殊限制。

\(1 \leq k \leq n \leq 415, 1 \leq u,v \leq n\)

CODE
    
//2024.8.18
//by white_ice 
//送给好友的礼物 | P7276
#include
//s#include"need.cpp"
using namespace std;
#define itn int
constexpr itn oo = 450;
constexpr int inf = 0x7fffffff;
int n,k;
struct nod{itn v,nxt;}st[oo<<1];int cnt,head[oo];
void add(int x,int v){st[++cnt]=(nod){v,head[x]};head[x]=cnt;}
int fa[oo],siz[oo],f[oo][oo<<1];
bool vis[oo];
bool dfs(int x){
	bool fruit=0;
	for(int i=head[x];i;i=st[i].nxt){
		int v=st[i].v;
		if(v==fa[x]||!v) continue;
		fa[v]=x;
		bool now=dfs(v);
		if(!now) st[i].v=0;
		fruit|=now;
	}
	return fruit|vis[x];
}
void solve(int x){
	siz[x]=1; f[x][0]=0;
	for(int l=head[x];l;l=st[l].nxt){
		int v=st[l].v;
		if(v==fa[x]||!v) continue;
		solve(v);
		siz[x]+=siz[v];
		for(int i=(siz[x]-1)*2;i>=0;i--){
			f[x][i]=f[x][i]+f[v][0]+2;
			if(i>=siz[v]*2) f[x][i]=min(f[x][i],f[x][i-siz[v]*2]+f[v][(siz[v]-1)*2]);
			for(int j=min((siz[v]-1)*2,i-2);j>=0;j--)
				f[x][i]=min(f[x][i],f[x][i-j-2]+f[v][j]+2);
		}
	}
}
main(void){
    //fre();
    cin.tie(0)->sync_with_stdio(0);
	memset(f,0x3f,sizeof(f));
	cin >> n >> k;
	for(int x,y,i=1;i<n;i++){ cin="">> x >> y;
		add(x,y),add(y,x);
	}
	for(int x,i=1;i<=k;i++){cin >> x;vis[x]=1;}
	dfs(1);
	solve(1);
	int out=inf;
	for(int i=0;i<=(siz[1]-1)*2;i++)
		out=min(out,max(i,f[1][i]));
	cout << out << flush;
	exit (0);
}
	

P7276 送给好友的礼物 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)在这里看吧。。。


T5 广播
时间限制: 2 s   内存限制: 512 MB   测评类型: 传统型

题目描述

C 国有 \(n\) 个城市,非常巧合的是这 \(n\) 个城市刚好构成了一棵树。C 国的国王是位日理千机的贤君,为了能及时发布自己的命令,于是决定在每个城市都建造一个信号塔,信号塔能传播信息,城市\(i\) 的信号塔的传播能力是\(val_i\): 表示如果城市\(i\) 和城市\(j\) 的距离\(dist(i, j) \leq val_i\),那么就能把信息从城市\(i\) 传到城市\(j\)。国王所在的城市为\(1\) 号城市,国王想尽可能快的让自己发布的命令在\(i\) 号城市被执行,所以他希望把命令从 \(1\) 号城市传播到 \(i\) 号城市这个过程中的传播次数尽可能少。输出从 \(1\) 号城市到 \(i\) 号城市所需的最少传播次数。

输入格式

输入的第一行有一个正整数\(n\),表示城市数量。

接下来一行有\(n\) 个正整数,表示传播距离\(val\)。

接下\(n-1\) 行每行有个正整数\(x_i,y_i\),表示一条边。

输出格式

输出一行\(n-1\) 个正整数,用空格隔开,表示答案。

样例

input

8
1 3 1 1 1 1 1 1
1 2
1 3
1 4
2 5
2 6
3 7
3 8

output

1 1 1 2 2 2 2

数据范围与提示

保证输入的边形成一棵树。

对于\(20\%\) 的数据,有\(n \leq 1000\);

对于接下来\(10\%\) 的数据,有\(n \leq 2 \times 10^5\),且是一棵完全二叉树;

对于接下来\(10\%\) 的数据,有\(n \leq 2 \times 10^5\),且是一条链;

对于接下来\(20\%\) 的数据,有\(n \leq 50000\);

对于接下来\(40\%\) 的数据,有\(n \leq 2 \times 10^5\)。

时间限制:$ 2 \text{s}$

空间限制:\(512 \text{MB}\)

是的,有T5

我们将原图转化成新图,将节点\(i\)和距离它小于\(val_i\)的所有点连边,

考虑优化建边过程,

使用点分治优化即可

最后的图刚好是个01bfs,直接跑就好

标签:oo,10,leq,2024.8,18,样例,int,毛毛虫
From: https://www.cnblogs.com/white-ice/p/18366192

相关文章

  • 代码随想录Day18
    530.二叉搜索树的最小绝对差给你一个二叉搜索树的根节点root,返回树中任意两不同节点值之间的最小差值。差值是一个正数,其数值等于两值之差的绝对值。示例1:输入:root=[4,2,6,1,3]输出:1示例2:输入:root=[1,0,48,null,null,12,49]输出:1提示:树中节点的数目范围是......
  • Leetcode每日刷题之18.四数之和
    1.题目解析这里的18.四数之和与之前的三数之和有着异曲同工之妙,所以建议看完三数之和再来看本题,详细题目见Leetcode每日刷题之15.三数之和 ,只不过这里需要寻找的是四元组,也是不能寻找重复的四元组并且四元组内的数字可以按照任意顺序返回2.算法原理关于四数之和的思路......
  • (附论文)基于Springboot和Vue的社区养老服务平台管理系统(187)
    获取源码请滑到最底部访问官网项目配套调试视频和相对应的软件安装包1、项目描述具体请看视频演示2、项目开发工具开发工具:Idea或Eclipse数据库:MysqlJar包仓库:Maven前端框架:Vue后端框架:Springboot3、项目图片4、演示视频(附论文)基于Springboot和Vue的社区养老......
  • (附论文)基于Springboot和Vue的校园商铺管理系统(188)
    获取源码请滑到最底部访问官网项目配套调试视频和相对应的软件安装包1、项目描述本次开发的校园商铺管理系统实现了收货地址管理、购物车管理、字典管理、公告信息管理、商家管理、商品管理、商品收藏管理、商品评价管理、商品订单管理、用户管理、管理员管理等功能。具体请......
  • 2024.8.18 鲜花
    鱼,好大的鱼,虎纹鲨鱼回リ続ける歯车には成リ下がらない平均演じる诞生から始まった地狱游び半分で神が导いた盤上の世界NONONOGAMENOLIFEぬるい平穏をばっさリ切リ舍てて栄光への阶段に存在刻むんだ目に映るのは完全胜利の运命何もかも计算どおり変えて......
  • 2024.8.18 周总结(上周天到这周六集训,这周天放假)
    感觉这一周上难度了,尤其没听懂的是二分图和博弈论那天上午休息完之后的部分。有复习,有新知识,收获还是比较大的。晚上打游戏打多了。文化课没学多少。中午看番、玩寝室楼下桌上的游戏去了,因为寝室要关灯拉窗帘睡得也更早,一周就只写了一点点字帖,看了一点点《乡土中国》。综......
  • 学习笔记 韩顺平 零基础30天学会Java(2024.8.14)
    P500集合体系图     单列集合是指自己只有一个值,双列集合是像键值对这样的P501Collection方法     对于第三点,像Set这样的,存放进去的和取出来的顺序可能不是一样的,所以就叫无序的P502迭代器遍历在调用iterator.next()方法之前必须要调用iterator.ha......
  • AIGC时代算法工程师的面试秘籍(第二十式2024.8.5-8.18) |【三年面试五年模拟】
    写在前面【三年面试五年模拟】旨在整理&挖掘AI算法工程师在实习/校招/社招时所需的干货知识点与面试方法,力求让读者在获得心仪offer的同时,增强技术基本面。也欢迎大家提出宝贵的优化建议,一起交流学习......
  • 对象流,序列化和反序列化 day18
    packagecom.shujia.day18.ketang;importjava.io.*;/*序列化流:序列化:将一个对象转换成网络中传输的流对象输出流:ObjectOutputStream将一个类的对象写进文本中反序列化:将网络中传输的流还原成一个对象对象输入流:Object......
  • Leetcode每日一题 20240818 551.学生出勤记录Ⅰ
    题目描述给你一个字符串s表示一个学生的出勤记录,其中的每个字符用来标记当天的出勤情况(缺勤、迟到、到场)。记录中只含下面三种字符:‘A’:Absent,缺勤‘L’:Late,迟到‘P’:Present,到场如果学生能够同时满足下面两个条件,则可以获得出勤奖励:按总出勤计,学生缺勤(‘A’)严......