題目描述
有一些黑白區間 \([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 ...