【学习笔记】AGC035

Develop

d p dp dp好题!!

转化是显然的。删除的点集是合法的当且仅当其导出子图不存在环。

如果 K K K是偶数,那么按编号奇偶性考虑,问题转化为不能取连续 k 2 + 1 \frac{k}{2}+1 2k+1个数。

如果 K K K是奇数,那么一个环可以看成两个交叉的边加上左右两段连续区间。

考虑把 x x x x + K x+K x+K划分到同一层。对于每一层,考虑把左右侧的点一起转移。

d p [ i ] [ j ] [ k ] dp[i][j][k] dp[i][j][k]表示前 i i i层,向上向右再向上的最大路径长度为 j j j,右边点选了连续 k k k个的方案数。

1.1 : 1.1: 1.1:若左右边的点都不选, d p [ i − 1 ] [ j ] [ k ] → d p [ i ] [ 0 ] [ 0 ] dp[i-1][j][k]\to dp[i][0][0] dp[i1][j][k]dp[i][0][0]
1.2 : 1.2: 1.2:若选左边的点,不选右边的点,那么从这个点可以往上爬, d p [ i − 1 ] [ 0 ] [ k ] → d p [ i ] [ 0 ] [ 0 ] dp[i-1][0][k]\to dp[i][0][0] dp[i1][0][k]dp[i][0][0] d p [ i − 1 ] [ j ] [ k ] → d p [ i ] [ j + 1 ] [ 0 ] [ j > 0 ] dp[i-1][j][k]\to dp[i][j+1][0][j>0] dp[i1][j][k]dp[i][j+1][0][j>0]
1.3 : 1.3: 1.3:若不选左边的点,选右边的点, d p [ i − 1 ] [ j ] [ k ] → d p [ i ] [ 0 ] [ k + 1 ] dp[i-1][j][k]\to dp[i][0][k+1] dp[i1][j][k]dp[i][0][k+1]
1.4 : 1.4: 1.4:若左右两边的点同时选,那么可以向上爬或者直接往右边走, d p [ i − 1 ] [ 0 ] [ k ] → d p [ i ] [ k + 2 ] [ k + 1 ] dp[i-1][0][k]\to dp[i][k+2][k+1] dp[i1][0][k]dp[i][k+2][k+1] d p [ i − 1 ] [ j ] [ k ] → d p [ i ] [ j + 1 ] [ k + 1 ] [ j > 0 ] dp[i-1][j][k]\to dp[i][j+1][k+1][j>0] dp[i1][j][k]dp[i][j+1][k+1][j>0]

然后可以根据最大路径长度来判断是否存在环,即 j ≤ K + 1 j\le K+1 jK+1。复杂度 O ( n 3 ) O(n^3) O(n3)

tips:图论模型,状态设计与转移

Long Common Subsequence

这个构造题做过。输出 n n n 0 0 0 n n n 1 1 1,一个 0 0 0即可。

Equal LIS

神仙构造题。结论题

f [ i ] f[i] f[i]表示以 i i i结尾的 L I S LIS LIS的长度。 L L L表示整个序列 L I S LIS LIS的长度。

f [ i ] f[i] f[i]具有一些分层的性质。若 L L L为偶数那么把 f [ i ] ≤ L 2 f[i]\le \frac{L}{2} f[i]2L扔到 A A A集合, f [ i ] > L 2 f[i]>\frac{L}{2} f[i]>2L扔到 B B B集合。

如果 L L L为奇数,那么考虑第一个集合中是否存在一个位置,使得第一个集合 L I S LIS LIS不变,另一个集合的 L I S LIS LIS 1 1 1

被hack了233

如果有一个数不在 L I S LIS LIS中,那么把包含它的长度 ⌈ L 2 ⌉ \lceil\frac{L}{2}\rceil 2L I S IS IS拿出来,剩下数的 L I S LIS LIS至少是 ⌈ L 2 ⌉ \lceil\frac{L}{2}\rceil 2L

显然 L I S LIS LIS f [ i ] f[i] f[i]编号非常有特色。首先把这个 I S IS IS扔到 A A A集合,设这个 I S IS IS组成的集合为 { f [ i ] } \{f[i]\} {f[i]}。然后把剩下的数中 f [ j ] ∉ { f [ i ] } f[j]\notin \{f[i]\} f[j]/{f[i]}的数放进 B B B集合。然后再在 L I S LIS LIS剩的数中随便选一个放进 B B B集合。剩下的边角料放进 A A A集合。

显然这个构造是合法的。

#include<bits/stdc++.h> #define fi first #define se second #define ll long long #define pb push_back #define db double #define inf 0x3f3f3f3f3f3f3f3f using namespace std; int T,n,p[200005],vis[200005],vis2[200005],f[200005],g[200005],bit[200005]; void add(int x,int y){ for(;x<=n;x+=x&-x)bit[x]=max(bit[x],y); } int get(int x){ int y=0;for(;x;x-=x&-x)y=max(y,bit[x]); return y; } int solve(){ cin>>n; for(int i=1;i<=n;i++)cin>>p[i]; for(int i=1;i<=n;i++)bit[i]=vis[i]=vis2[i]=0; for(int i=1;i<=n;i++)add(p[i],f[i]=get(p[i])+1); for(int i=1;i<=n;i++)bit[i]=0; for(int i=n;i>=1;i--)add(n-p[i]+1,g[i]=get(n-p[i]+1)+1); int L=0;for(int i=1;i<=n;i++)L=max(L,f[i]); if(L%2==0)return 1; for(int i=1;i<=n;i++)if(f[i]+g[i]-1==L&&!vis[f[i]])vis[f[i]]=vis2[i]=1; for(int i=1;i<=n;i++)if(f[i]+g[i]-1>=(L+1)/2&&!vis2[i])return 1; return 0; } int main(){ ios::sync_with_stdio(false); cin.tie(0),cout.tie(0); cin>>T; while(T--){ cout<<(solve()?"YES":"NO")<<"\n"; } }

Rabbit Exercise

将原序列差分,令 d [ i ] = X [ i ] − X [ i − 1 ] d[i]=X[i]-X[i-1] d[i]=X[i]X[i1],会发现很有意思的现象,每次操作相当于交换 d [ i ] d[i] d[i] d [ i + 1 ] d[i+1] d[i+1]的值。

f [ i ] [ j ] f[i][j] f[i][j]表示初始在 i i i,经过 2 j 2^j 2j次操作后的位置。复杂度 O ( n log ⁡ K ) O(n\log K) O(nlogK)

Synchronized Subsequence

字符串 d p dp dp 233

考虑规划后缀。 f ( i ) f(i) f(i)表示只考虑 ≥ i \ge i i a a a b b b的最大字典序

b b b a a a的前面,那么会贪心的在从左往右每个 a a a前面插入最多的 b b b,显然新增的 a a a会被挂在最后面。直到不存在这样的 j j j,设这一串操作得到的串是 s s s,那么 f ( i ) = s + f ( j ) f(i)=s+f(j) f(i)=s+f(j)

b b b a a a的后面,那么显然不会在中间插 a a a,那么直接找到第一个不会插到中间的 j j j f ( i ) = a b + f ( j ) f(i)=ab+f(j) f(i)=ab+f(j)

复杂度 O ( n 2 ) O(n^2) O(n2)因为要字符串比较

tips:字符串 d p dp dp考虑拼接,性质。

Reversing and Concatenating

设最小的字母是 a a a,显然你经过 log ⁡ n \log n logn轮后就全部变成 a a a

然后显然你每次会提取逆序字典序最小的那个

可以直接用 string \text{string} string模拟。

Complexity

如果我折半的话凌乱度不会超过 log ⁡ n \log n logn

f i , j , k , l f_{i,j,k,l} fi,j,k,l表示 i i i [ j , k ] [j,k] [j,k]向下凌乱度不超过 l l l的最大长度

g i , j , k , l g_{i,j,k,l} gi,j,k,l表示 i i i [ j , k ] [j,k] [j,k]向右凌乱度不超过 l l l的最大长度

转移方程如下。(233

f i + f i , j , k , l , j , k , l − 1 + f i , j , k , l − 1 → f i , j , k , l f_{i+f_{i,j,k,l},j,k,l-1}+f_{i,j,k,l-1}\to f_{i,j,k,l} fi+fi,j,k,l,j,k,l1+fi,j,k,l1fi,j,k,l

k − j + 1 → g j , i , i + f i , j , k , l − 1 , l k-j+1\to g_{j,i,i+f_{i,j,k,l}-1,l} kj+1gj,i,i+fi,j,k,l1,l

f i , j , k + 1 , l → f i , j , k , l f_{i,j,k+1,l}\to f_{i,j,k,l} fi,j,k+1,lfi,j,k,l

g i + g i , j , k , l , j , k , l − 1 + g i , j , k , l − 1 → g i , j , k , l g_{i+g_{i,j,k,l},j,k,l-1}+g_{i,j,k,l-1}\to g_{i,j,k,l} gi+gi,j,k,l,j,k,l1+gi,j,k,l1gi,j,k,l

k − j + 1 → f j , i , i + g i , j , k , l − 1 , l k-j+1\to f_{j,i,i+g_{i,j,k,l}-1,l} kj+1fj,i,i+gi,j,k,l1,l

g i , j , k + 1 , l → g i , j , k , l g_{i,j,k+1,l}\to g_{i,j,k,l} gi,j,k+1,lgi,j,k,l

注意细节。先处理跨层的转移。

复杂度 O ( n 3 log ⁡ n ) O(n^3\log n) O(n3logn)


__EOF__

本文作者仰望星空的蚂蚁
本文链接https://www.cnblogs.com/cqbzly/p/17530107.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   仰望星空的蚂蚁  阅读(6)  评论(0编辑  收藏  举报  
相关博文:
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· DeepSeek 开源周回顾「GitHub 热点速览」
历史上的今天:
2021-08-05 【题解】[POI2005] SZA-Template
2021-08-05 【题解】[POI2008] BBB-BBB
点击右上角即可分享
微信分享提示