牛客暑假第六場 K bag 差分 思維

2021-10-08 17:44:36 字數 1973 閱讀 4159

題意:給你一段長度為n的序列判斷是否為k-bag的子串行,定義k-bag為k個數的全排列

思路:這題的思路有很多,有hash+map,有dp,也有差分。說一下差分把,首先對與這段序列,有開頭一定在1~min(k,n)之間,用乙個陣列維護這段區間,如果這個陣列t[i]的字首和等於0,那麼就表示這個位置可以作為開頭,反之則不能,基於這個結論,對兩個相同的數字之間的的距離進行分類,如果兩個數字之間的距離》=k,即表示1~k都是可以作為開頭的,如果小於k,那麼就表示這個區間必有乙個位置為開頭,如果 這個序列的 第乙個區間開頭是 x1,那麼後面的區間開頭一定是 x1+y*k,y是乙個整數,那麼 我只要把當前開頭 % k 就可以得到第一區間的開頭,這個值可以加到第乙個區間開頭。這個區間值 +1 的操作可以用差分陣列維護

具體**如下:

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

using

namespace std;

typedef

long

long ll;

typedef

unsigned

long

long ull;

typedef pair<

int,

int> pii;

#define rep(i, a, n) for(int i = a; i <= n; i++)

#define per(i, a, n) for(int i = n; i >= a; i--)

#define ios std::ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);

#define fopen freopen("file.in","r",stdin);freopen("file.out","w",stdout);

#define fclose fclose(stdin);fclose(stdout);

#define pi 3.14159265358979323846

const

int inf =

1e9;

const ll onf =

1e18

;const

int maxn =

5e5+10;

inline

intread()

while

(isdigit

(ch)

)return x*f;

}int t[maxn]

, a[maxn]

, ord[maxn]

;bool

cmp(

int x,

int y)

inline

boolcf(

)if(!flag)

return0;

for(

int i =

1; i <= n; i++

) ord[i]

=i;stable_sort

(ord+

1, ord+n+

1, cmp)

;int sz =

min(n, k)

;for

(int i =

1; i <= sz; i++

) t[i]=0

;for

(int i =

2; i <= n; i++)}

for(

int i =

1; i <= sz; i++

)return0;

}signed

main()

else

puts

("no");

}return0;

}

2020暑期牛客第六場 K Bag(思維,字首)

收穫 對於乙個長度為k的區間是否存在 l,l k 1 l,l k 1 l,l k 1 的所有數字,可以用區間和和區間異或和來判別。思路 對於前後殘缺的區間可以預處理出前字尾中不同數字的個數,然後列舉分割點,對於完整的區間用區間和和區間異或和判斷。ll a n xor n sum n ll n,k,s...

牛客多校第六場 K Bag(暴力,貪心)

題意 原序列是一堆k個數全排列組成的。給你乙個串,求這個子串是否可能是原序列子串 思路 直接暴力啊,維護出dp i dp i dp i 代表i ii i k 1i k 1 i k 1是否是全排列,然後列舉第乙個排列的終止位置。列舉起始排列的複雜度為k kk,check的複雜度為n k n kn k,...

牛客多校第六場

d 題意感覺說的不是很清楚,一開始題意弄錯了,以為是最優的方案,結果是對於每個盒子這個 so clever 的人的做法是優先選擇盡可能大的物品裝完乙個盒子,我就不知道這個人 聰明了。思路 賽後知道題意後,5分鐘寫完,瞎暴力就一發過了,我自己都有點出乎意料真水了。includeusing namesp...