省選集訓2022 模擬賽14

2022-10-08 22:39:22 字數 1842 閱讀 9248

題目描述

有一些黑白區間 \([l_i,r_i]\),有些區間已經被指定了顏色,有些區間還沒有。你需要指定未染色區間的顏色,使得對於數軸上每個點,覆蓋他的黑區間和白區間個數差的絕對值 \(\leq 1\)

\(n\leq 10^9,m\leq 3\cdot 10^4\)

解法

事實上看到這個差的絕對值 \(\leq 1\) 我的 \(\tt dna\) 就有反應了,好像集訓隊作業中有類似的題,但是我沒有回想起來,只是差值絕對值 \(\leq 1\) 這個問題,它可能指向尤拉迴路。

可以把點按被覆蓋次數分為奇覆蓋和偶覆蓋,首先考慮都是偶覆蓋的情況。這時有乙個特別強的限制:因為所有點最後差值都是 \(0\),所以我們把黑看成 \(1\),白看成 \(-1\),那麼差分陣列一定全為 \(0\)

對於黑區間,它對差分陣列的影響是 \(s[l_i]\leftarrow +1\),\(s[r_i+1]\leftarrow -1\);對於白區間,它對差分陣列的影響是 \(s[l_i]\leftarrow -1\),\(s[r_i+1]\leftarrow +1\),我們可以把差分陣列看成度數,那麼差分陣列全為 \(0\) 就等價於多源點尤拉迴路的充要條件:入度\(=\)出度。

所以黑區間可以看成 \(l_i\rightarrow r_i+1\) 的邊,白區間可以看成 \(r_i+1\rightarrow l_i\) 的邊,現在我們要把未染色的邊定向,使得此圖存在尤拉迴路,那麼就是乙個混合圖尤拉迴路,可以用網路流解決。

那麼存在奇覆蓋怎麼做呢?考慮把這些點新增一條 \(i - i+1\) 未定向的邊,如果度數是 \(-1\) 這條邊就會把度數調整成 \(0\),如果度數是 \(1\) 這條邊就會把度數調整成 \(0\),直接跑網路流即可。

#include #include #include #include using namespace std;

const int m = 60005;

const int inf = 0x3f3f3f3f;

int read()

while(c>='0' && c<='9')

return x*f;

}int n,m,l[m],r[m],w[m],a[m],in[m],pre[m];

int s,t,tot=1,f[m],d[m],cur[m],id[m];

struct edgee[m*10];

void add(int u,int v,int c)

,f[u]=tot;

e[++tot]=edge,f[v]=tot;

}int bfs()

} }return 0;

}int dfs(int u,int ept)

} return flow;

}signed main()

sort(a+1,a+1+m);m=unique(a+1,a+1+m)-a-1;

for(int i=1;i<=n;i++) }

for(int i=1;i<=m;i++)

if((pre[i]+=pre[i-1])&1)

s=0;t=m+1;int sum=0;

for(int i=1;i<=m;i++)

if(in[i]>0) add(s,i,in[i]/2),sum+=in[i]/2;

if(in[i]<0) add(i,t,(-in[i])/2);

} while(bfs())

if(sum)

for(int i=1;i<=n;i++)

}

省選集訓2022 模擬賽6

題目描述 定義長度為 n 的好串 s 滿足 給你長度為 n 的序列 a 和 v 分別表示原序列和價值序列。你每次可以選擇乙個原序列中的好串,將其刪除之後剩下的串會前後拼接。設這次刪除的長度是 l 那麼會得分 v l 問最大得分,不一定要把原序列刪完。n leq 400,v i leq 10 5,a ...

省選集訓2022 模擬賽8

題目描述 給定乙個 n times m 的 01 矩陣,對於矩陣的每乙個位置,你需要對於這個位置上的值反轉,然後求出這個矩陣的秩的變化 0 可以將這個矩陣看成 n 個大小為 0,2 m 的數,秩就是它們線性基的大小。n,m leq 1000 解法 我們判斷求出原先的 n 個向量在原來的線性基中是可以...

省選集訓2022 模擬賽10

題目描述 給定 n 個元素,每個元素有兩個屬性值 a i,b i 我們可以將其以任意順序排列,要最大化下式 min a i i cdot k max b i i cdot k n leq 10 5,a i,b i,kn leq 10 9 解法 應該是遇到困難退大火才對,直接使用列舉法,考慮列舉 m ...