link:密碼系統
容易發現一共有k種不同的劃分 而每種劃分中我們要求出字典序最大的那個然後和其他的比較求出字典序最小的。
先考慮如何求出最大的 容易發現這是字典序的問題 求出sa陣列然後倒著掃瞄就行了 分段的話按i%k分即可。
求出最大的了之後考慮如何求出最小的 容易發現還是sa陣列看一下他們之間的相對位置 靠前的必然字典序要優。
值得一提的是 字尾陣列雖然難寫 但是思想很好懂 按照思想來寫不容易寫錯 而不是靠硬背。
//#include#include#include#include#include#include#include#include#include#include#include#include#include#include#include#include#include#include#include#define ll long long
#define db double
#define inf 1000000000
#define ldb long double
#define pb push_back
#define get(x) x=read()
#define gt(x) scanf("%d",&x)
#define put(x) printf("%d\n",x)
#define putl(x) printf("%lld\n",x)
#define gc(a) scanf("%s",a+1)
#define rep(p,n,i) for(re int i=p;i<=n;++i)
#define go(x) for(int i=lin[x],tn=ver[i];i;tn=ver[i=nex[i]])
#define fep(n,p,i) for(re int i=n;i>=p;--i)
#define pii pair#define mk make_pair
#define re register
#define p 1000000007
#define s second
#define f first
#define mod 998244353
#define gf(x) scanf("%lf",&x)
#define pf(x) ((x)*(x))
#define ull unsigned long long
#define ui unsigned
using namespace std;
char buf[1<<15],*fs,*ft;
inline char getc()
inline int read()
while(ch>='0'&&ch<='9')
return x*f;
}const int maxn=1000010<<1;
int n,m,k;
char a[maxn];int vis[maxn];
int c[maxn],x[maxn],y[maxn],sa[maxn],rk[maxn],h[maxn];
inline void sa()
rep(1,n,i)rk[sa[i]]=i;
}inline void get_h()
}int main()
rep(sa[st],sa[st]+k-1,i)putchar(a[i]);
return 0;
}
牛客挑戰賽58
前i 1的二進位制相等,a的前n個數的前i 1位可以亂取,b的前n 1個數前i 1位也可以亂取,因為b的第n個數的前i 1異或可為任意值,所以sum1 2 i 1 n 2 i 1 n 1 2 i 1 2n 1 a的第i位為1且b的第i位為0 只要a的n數第i位中有乙個不為0的,a的第i位不為0,b的...
牛客Wannafly挑戰賽12 題解
傳送門 說是比賽題解,其實我只會前三題 後面的一定補 t1題意,在乙個長度為n的時間內,問如何選擇存款期限,使得收益最大。dp include include include include using namespace std define fi first define se second d...
日常摸魚 牛客挑戰賽3
無 期望dp,要用字首和優化一下。略了 比較水的追及問題。但是兩個點一開始就在一起要特判掉。稍微轉化一下。只用求數列中任意兩對數的和的位數,這個可以隨便套資料結構。思路大致跟上一場蝴蝶差不多。而且比上場那個簡單多了,連資料結構都不用套。給定乙個n個點的樹,以1為根,邊權都是1。乙個人從起點s開始隨機...