题解 CF1392G Omkar and Pies
Solution
可以想到的是,如果我们选了区间 \([L,R]\),那么相当于我们对 \(s\) 进行 \([L,n]\) 的操作,对 \(t\) 进行 \([R+1,n]\) 的操作(注意一定得是后缀,因为前缀换是前面的)。
那么我们就可以对于每一个后缀都求出 \(s,t\) 的变化情况,然后直接枚举两者交集的 \(1\) 个数即可。因为答案只跟交集中 \(1\) 的个数有关。
复杂度 \(\Theta(nk+k2^k)\) 。
Code
#include <bits/stdc++.h>
using namespace std;
#define Int register int
#define MAXM 1000005
#define MAXN 25
template <typename T> inline void read (T &t){t = 0;char c = getchar();int f = 1;while (c < '0' || c > '9'){if (c == '-') f = -f;c = getchar();}while (c >= '0' && c <= '9'){t = (t << 3) + (t << 1) + c - '0';c = getchar();} t *= f;}
template <typename T,typename ... Args> inline void read (T &t,Args&... args){read (t);read (args...);}
template <typename T> inline void write (T x){if (x < 0){x = -x;putchar ('-');}if (x > 9) write (x / 10);putchar (x % 10 + '0');}
template <typename T> inline void chkmax (T &a,T b){a = max (a,b);}
template <typename T> inline void chkmin (T &a,T b){a = min (a,b);}
int n,m,k,tx[MAXM],ty[MAXM],s1[MAXN],s2[MAXN],sa[MAXN],sb[MAXN],Sa[1 << 20],Sb[1 << 20],siz[1 << 20],tmpa[MAXN],tmpb[MAXN];
void putout (int S){
for (Int i = 0;i < k;++ i) cout << (S >> i & 1);
}
struct node{
int pos[MAXN];
node operator + (const node &p)const{
node New;
for (Int i = 1;i <= k;++ i) New.pos[i] = p.pos[pos[i]];
return New;
}
};
signed main(){
read (n,m,k);int p = 0,q = 0;
for (Int i = 1;i <= k;++ i) scanf ("%1d",&s1[i]),sa[i] = s1[i],p += s1[i];
for (Int i = 1;i <= k;++ i) scanf ("%1d",&s2[i]),sb[i] = s2[i],q += s2[i];
for (Int i = 1;i <= n;++ i) read (tx[i],ty[i]);memset (Sa,0x3f,sizeof (Sa));
node fuc;
for (Int i = 1;i <= k;++ i) fuc.pos[i] = i;
for (Int i = n + 1;i >= 1;-- i){
node f;
for (Int h = 1;h <= k;++ h) f.pos[h] = h;
swap (f.pos[tx[i]],f.pos[ty[i]]),fuc = f + fuc;
int ta = 0,tb = 0;
for (Int h = 1;h <= k;++ h) tmpa[fuc.pos[h]] = sa[h],tmpb[fuc.pos[h]] = sb[h];
for (Int h = k;h >= 1;-- h) ta = ta << 1 | tmpa[h],tb = tb << 1 | tmpb[h];
chkmin (Sa[ta],i),chkmax (Sb[tb],i);
}
for (Int i = 0;i < k;++ i)
for (Int s = (1 << k) - 1;~s;-- s) if (!(s >> i & 1)) chkmin (Sa[s],Sa[s + (1 << i)]),chkmax (Sb[s],Sb[s + (1 << i)]);
int ans = 0;
for (Int s = 0;s < (1 << k);++ s) siz[s] = siz[s >> 1] + (s & 1);
for (Int s = 0;s < (1 << k);++ s) if (Sb[s] - Sa[s] >= m && siz[s] > siz[ans]) ans = s;
write (siz[ans] * 2 + k - p - q),putchar ('\n');
write (Sa[ans]),putchar (' '),write (Sb[ans] - 1),putchar ('\n');
return 0;
}