我想建个网站,怎么弄网站做网站卖东西,网站服务器租用,wordpress 修订版本正题
题目链接:https://www.luogu.com.cn/problem/AT4502 题目大意
给出nnn个长度SSS#xff0c;求一个最小mmm表示用大小为mmm的字符集构造出nnn个符合对应长度的字符串使得字符串按照给出顺序从小到大。 1≤n≤2105,1≤Si≤1091\leq n\leq 2\times 10^5,1\leq S_i\leq 10^…正题
题目链接:https://www.luogu.com.cn/problem/AT4502 题目大意
给出nnn个长度SSS求一个最小mmm表示用大小为mmm的字符集构造出nnn个符合对应长度的字符串使得字符串按照给出顺序从小到大。
1≤n≤2×105,1≤Si≤1091\leq n\leq 2\times 10^5,1\leq S_i\leq 10^91≤n≤2×105,1≤Si≤109 解题思路
先二分答案然后每次构造最小的能构造的就行了。考虑怎么构造最小的。
如果这个字符串比上一个要长那么显然在上一个后面补上最小的字符就是最优的。
否则我们把上一个字符串截断到目前长度然后类似于进位的方法来让最后一个位置加上111。
因为字符串长度很长所以比较难办开始写了个线段树发现过不了。
其实用栈维护每一个不是最小字符的位置就好了这些位置不会很多的进位就暴力递归进位。
时间复杂度O(nlogn)O(n\log n)O(nlogn) code
#includecstdio
#includecstring
#includealgorithm
using namespace std;
const int N2e510;
int n,a[N],s[N],k[N],top;
void ins(int x,int w){while(s[top]x)top--;if(s[top]!x)s[top]x,k[top]1;else k[top];if(top1k[top]w)top--,ins(x-1,w);
}
bool check(int w){top1;k[1]s[1]0;for(int i2;in;i)if(a[i]a[i-1]){if(w1)return 0;ins(a[i],w);}return !k[1];
}
int main()
{scanf(%d,n);for(int i1;in;i)scanf(%d,a[i]);int l1,rn;while(lr){int mid(lr)1;if(check(mid))rmid-1;else lmid1;}printf(%d\n,l);return 0;
}