A题
题目描述:春天到了,该练习 dp 了
gjlccc 给出了一个序列 b1,b2,...,bm 让 Silly_Tape 做一个动态规划,有 (m+1)^2 个状态 dp[i][j](0≤i,j≤m) ,状态转移式为:
dp[i][j]={ 0(i=0)
b[i]+dp[i−1][j](i>0,j=0)
b[i]+max{dp[i−1][j],dp[i−1][j−1]+i2}(i>0,j>0)
}
Silly_tape 认为这题太容易了,于是这题就到了你的手上。
给定一个序列 a1,a2,...,an与 q次询问。
在第 iii 次询问中,给你三个整数 l,r,k,请回答出当 gjlccc 选定 al,al+1,...,ara 作为初始序列时,写出 dp[m][k] 的值,m=r−l+1,bj=al+j−1(1≤j≤m)。
解题:
找规律简化过程。
AC代码:
#include<bits/stdc++.h>
using namespace std;
const int N=1e6+10;
long long a[N],t,sum1[N],sum2[N];
int main(){
ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
cin>>t;
while(t--){
int n;
cin>>n;
for(int i=1;i<=n;i++){
cin>>a[i];sum1[i]=sum1[i-1]+a[i];
sum2[i]=i*i;
sum2[i]+=sum2[i-1];
}
int q;
cin>>q;
while(q--){
int l,r,k;
long long ans=0;
cin>>l>>r>>k;
if(k<r-l+1)ans=sum1[r]-sum1[l-1]+sum2[r-l+1]-sum2[abs(r-l+1-k)];
else ans=sum1[r]-sum1[l-1]+sum2[r-l+1];
cout<<ans<<endl;
}
}
return 0;
}
B题
题目描述:痴呆邦 · 第 k 等式
这是一项庞大的工程... 痴呆邦发动了全邦人民开始了 `第 k 等式` 工程。
所谓 `第 k 等式` 是指已知 A、B、C 三个数字分别表示等式 a+b=c中 a、b、c 的位数,不含前导零。你需要找出其中字典序第 k 小的等式。
这个等式意义重大,关乎痴呆邦未来一年的生产,现在痴呆邦急需你来帮助完成这项工程。
AC代码:
#pragma clang diagnostic push
#pragma ide diagnostic ignored "cppcoreguidelines-narrowing-conversions"
#pragma ide diagnostic ignored "hicpp-signed-bitwise"
#pragma GCC optimize ("Ofast,unroll-loops")
#pragma GCC optimize("no-stack-protector,fast-math")
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<ll, ll> pll;
typedef pair<int, int> pii;
typedef pair<double, double> pdd;
typedef vector<int> vi;
typedef vector<ll> vll;
typedef vector<double> vd;
typedef vector<string> vs;
typedef vector<vi> vvi;
typedef vector<vvi> vvvi;
typedef vector<vll> vvll;
typedef vector<vvll> vvvll;
typedef vector<pii> vpii;
typedef vector<vpii> vvpii;
typedef vector<pll> vpll;
typedef vector<vpll> vvpll;
typedef vector<pdd> vpdd;
typedef vector<vd> vvd;
#define yn(ans) printf("%s\n", (ans)?"Yes":"No");
#define YN(ans) printf("%s\n", (ans)?"YES":"NO");
template<class T> bool chmax(T &a, T b) {
if (a >= b) return false;
a = b; return true;
}
template<class T> bool chmin(T &a, T b) {
if (a <= b) return false;
a = b; return true;
}
#define FOR(i, s, e, t) for ((i) = (s); (i) < (e); (i) += (t))
#define REP(i, e) for (int i = 0; i < (e); ++i)
#define REP1(i, s, e) for (int i = (s); i < (e); ++i)
#define RREP(i, e) for (int i = (e); i >= 0; --i)
#define RREP1(i, e, s) for (int i = (e); i >= (s); --i)
#define all(v) v.begin(), v.end()
#define pb push_back
#define qb pop_back
#define pf push_front
#define qf pop_front
#define maxe max_element
#define mine min_element
ll inf = 1e18;
#define DEBUG printf("%d\n", __LINE__); fflush(stdout);
template<class T> void print(vector<T> &v, bool withSize = false) {
if (withSize) cout << v.size() << endl;
REP(i, v.size()) cout << v[i] << " ";
cout << endl;
}
mt19937_64 rng((unsigned int) chrono::steady_clock::now().time_since_epoch().count());
int __FAST_IO__ = []() {
std::ios::sync_with_stdio(0);
std::cin.tie(0);
std::cout.tie(0);
return 0;
}();
// Mint & Combinatorics
template <typename T>
T inverse(T a, T m) {
T u = 0, v = 1;
while (a != 0) {
T t = m / a;
m -= t * a; swap(a, m);
u -= t * v; swap(u, v);
}
return u;
}
template <typename T>
class Modular {
public:
using Type = typename decay<decltype(T::value)>::type;
constexpr Modular() : value() {}
template <typename U>
Modular(const U& x) {
value = normalize(x);
}
template <typename U>
static Type normalize(const U& x) {
Type v;
if (-mod() <= x && x < mod()) v = static_cast<Type>(x);
else v = static_cast<Type>(x % mod());
if (v < 0) v += mod();
return v;
}
const Type& operator()() const { return value; }
template <typename U>
explicit operator U() const { return static_cast<U>(value); }
constexpr static Type mod() { return T::value; }
Modular& operator+=(const Modular& other) { if ((value += other.value) >= mod()) value -= mod(); return *this; }
Modular& operator-=(const Modular& other) { if ((value -= other.value) < 0) value += mod(); return *this; }
template <typename U> Modular& operator+=(const U& other) { return *this += Modular(other); }
template <typename U> Modular& operator-=(const U& other) { return *this -= Modular(other); }
Modular& operator++() { return *this += 1; }
Modular& operator--() { return *this -= 1; }
Modular operator++(int) { Modular result(*this); *this += 1; return result; }
Modular operator--(int) { Modular result(*this); *this -= 1; return result; }
Modular operator-() const { return Modular(-value); }
template <typename U = T>
typename enable_if<is_same<typename Modular<U>::Type, int>::value, Modular>::type& operator*=(const Modular& rhs) {
#ifdef _WIN32
uint64_t x = static_cast<int64_t>(value) * static_cast<int64_t>(rhs.value);
uint32_t xh = static_cast<uint32_t>(x >> 32), xl = static_cast<uint32_t>(x), d, m;
asm(
"divl %4; \n\t"
: "=a" (d), "=d" (m)
: "d" (xh), "a" (xl), "r" (mod())
);
value = m;
#else
value = normalize(static_cast<int64_t>(value) * static_cast<int64_t>(rhs.value));
#endif
return *this;
}
template <typename U = T>
typename enable_if<is_same<typename Modular<U>::Type, long long>::value, Modular>::type& operator*=(const Modular& rhs) {
long long q = static_cast<long long>(static_cast<long double>(value) * rhs.value / mod());
value = normalize(value * rhs.value - q * mod());
return *this;
}
template <typename U = T>
typename enable_if<!is_integral<typename Modular<U>::Type>::value, Modular>::type& operator*=(const Modular& rhs) {
value = normalize(value * rhs.value);
return *this;
}
Modular& operator/=(const Modular& other) { return *this *= Modular(inverse(other.value, mod())); }
friend const Type& abs(const Modular& x) { return x.value; }
template <typename U>
friend bool operator==(const Modular<U>& lhs, const Modular<U>& rhs);
template <typename U>
friend bool operator<(const Modular<U>& lhs, const Modular<U>& rhs);
template <typename V, typename U>
friend V& operator>>(V& stream, Modular<U>& number);
private:
Type value;
};
template <typename T> bool operator==(const Modular<T>& lhs, const Modular<T>& rhs) { return lhs.value == rhs.value; }
template <typename T, typename U> bool operator==(const Modular<T>& lhs, U rhs) { return lhs == Modular<T>(rhs); }
template <typename T, typename U> bool operator==(U lhs, const Modular<T>& rhs) { return Modular<T>(lhs) == rhs; }
template <typename T> bool operator!=(const Modular<T>& lhs, const Modular<T>& rhs) { return !(lhs == rhs); }
template <typename T, typename U> bool operator!=(const Modular<T>& lhs, U rhs) { return !(lhs == rhs); }
template <typename T, typename U> bool operator!=(U lhs, const Modular<T>& rhs) { return !(lhs == rhs); }
template <typename T> bool operator<(const Modular<T>& lhs, const Modular<T>& rhs) { return lhs.value < rhs.value; }
template <typename T> Modular<T> operator+(const Modular<T>& lhs, const Modular<T>& rhs) { return Modular<T>(lhs) += rhs; }
template <typename T, typename U> Modular<T> operator+(const Modular<T>& lhs, U rhs) { return Modular<T>(lhs) += rhs; }
template <typename T, typename U> Modular<T> operator+(U lhs, const Modular<T>& rhs) { return Modular<T>(lhs) += rhs; }
template <typename T> Modular<T> operator-(const Modular<T>& lhs, const Modular<T>& rhs) { return Modular<T>(lhs) -= rhs; }
template <typename T, typename U> Modular<T> operator-(const Modular<T>& lhs, U rhs) { return Modular<T>(lhs) -= rhs; }
template <typename T, typename U> Modular<T> operator-(U lhs, const Modular<T>& rhs) { return Modular<T>(lhs) -= rhs; }
template <typename T> Modular<T> operator*(const Modular<T>& lhs, const Modular<T>& rhs) { return Modular<T>(lhs) *= rhs; }
template <typename T, typename U> Modular<T> operator*(const Modular<T>& lhs, U rhs) { return Modular<T>(lhs) *= rhs; }
template <typename T, typename U> Modular<T> operator*(U lhs, const Modular<T>& rhs) { return Modular<T>(lhs) *= rhs; }
template <typename T> Modular<T> operator/(const Modular<T>& lhs, const Modular<T>& rhs) { return Modular<T>(lhs) /= rhs; }
template <typename T, typename U> Modular<T> operator/(const Modular<T>& lhs, U rhs) { return Modular<T>(lhs) /= rhs; }
template <typename T, typename U> Modular<T> operator/(U lhs, const Modular<T>& rhs) { return Modular<T>(lhs) /= rhs; }
template<typename T, typename U>
Modular<T> power(const Modular<T>& a, const U& b) {
assert(b >= 0);
Modular<T> x = a, res = 1;
U p = b;
while (p > 0) {
if (p & 1) res *= x;
x *= x;
p >>= 1;
}
return res;
}
template <typename T>
bool IsZero(const Modular<T>& number) {
return number() == 0;
}
template <typename T>
string to_string(const Modular<T>& number) {
return to_string(number());
}
template <typename U, typename T>
U& operator<<(U& stream, const Modular<T>& number) {
return stream << number();
}
template <typename U, typename T>
U& operator>>(U& stream, Modular<T>& number) {
typename common_type<typename Modular<T>::Type, long long>::type x;
stream >> x;
number.value = Modular<T>::normalize(x);
return stream;
}
struct MOD {
static int value;
};
int MOD::value = 1e9+7;
using Mint = Modular<MOD>;
typedef vector<Mint> vm;
typedef vector<vm> vvm;
typedef vector<vvm> vvvm;
template <typename T> struct Discrete {
Discrete() {}
Discrete(vector<T> &v): p(v) {init();}
void add(T t) {
p.pb(t);
}
void init() {
sort(all(p));
p.resize(unique(all(p)) - p.begin());
}
int size() {return p.size();}
int id(T t) {
return lower_bound(all(p), t) - p.begin();
}
T operator[](int id) {return p[id];}
vector<T> &get() {return p;}
vector<T> p;
};
int main() {
int t;
cin >> t;
vi p(10, 1);
REP(i, 9) p[i + 1] = p[i] * 10;
while (t--) {
int A, B, C; ll K;
cin >> A >> B >> C >> K;
auto calc = [&](int x) {
if (x < p[A - 1]) return 0ll;
if (C == max(A, B)) {
if (A > B) {
int m = p[C] - p[B];
if (m >= x) {
return 1ll * (x - p[A - 1] + 1) * (p[B] - p[B - 1]);
} else {
int extra = min(x - m, p[B] - p[B - 1]), start = p[B] - p[B - 1] - 1;
return 1ll * (m - p[A - 1] + 1) * (p[B] - p[B - 1]) + 1ll * (start + start - extra + 1) * extra / 2;
}
} else {
int start = p[B] - p[A - 1] - p[B - 1];
int end = p[B] - p[A - 1];
chmin(x, end - 1);
int c = x - p[A - 1];
return 1ll * (start + start - c) * (c + 1) / 2;
}
} else {
if (A > B) {
int m = p[C - 1] - (p[B] - 1), m2 = p[C - 1] - p[B - 1];
if (x < m) return 0ll;
else if (x <= m2) {
int c = x - m + 1;
return 1ll * c * (c + 1) / 2;
} else {
int c = p[B] - p[B - 1];
return 1ll * c * (c + 1) / 2 + 1ll * c * (x - m2);
}
} else {
int start = p[A - 1], end = p[B] - p[B - 1];
int c = x - start + 1;
if (start + c - 1 < end) return 1ll * (start + start + c - 1) * c / 2;
else return 1ll * (start + end) * (end - start + 1) / 2 + 1ll * (c - (end - start + 1)) * end;
}
}
};
if (C == max(A, B) || C == max(A, B) + 1) {
int L = p[A - 1] - 1, R = p[A];
while (L + 1 < R) {
int mid = (L + R) >> 1;
ll sum = calc(mid);
if (sum >= K) R = mid; else L = mid;
}
if (R == p[A]) {
printf("-1\n");
} else {
ll sum = calc(L);
int X = L + 1, Y = K - sum;
if (C == max(A, B)) Y += p[B - 1] - 1;
else Y += max(p[B - 1], p[C - 1] - X) - 1;
int Z = X + Y;
printf("%d + %d = %d\n", X, Y, Z);
}
} else {
printf("-1\n");
}
}
return 0;
}
C题
题目描述:痴呆邦 · 附庸
随着痴呆邦的繁荣,越来越需要一种先进的制度引领痴呆邦未来的发展。城邦主们提议我们需要组建这样的联邦制度:
- 联邦需要具有唯一的最高联邦首领。
- 每个城邦主具有至多两个附庸,当然它们也可以没有附庸。
这个议案一经提出引来痴呆众和城邦主们的一致支持,这样城邦主们只需专注管理属于自己的两个附庸。实现痴呆邦繁荣的同时又实现 work life balance 是痴呆众一致的追求。
但是现在麻烦的事情复现了,已知存在 n 个城邦,这样的联邦制度存在多少种完全不同的附庸结构呢?
我们认为两个附庸结构不是完全不同的当且仅当可以通过交换任意次任意城邦主的左右附庸结构后得到完全相同的附庸结构。
输出描述:
每组测试数据输出一个整数,表示完全不同的附庸结构的数量对 998244353998244353998244353 取模的结果。
解题思路:找规律分支
AC代码:
#include <bits/stdc++.h>
using namespace std;
const int mod = 998244353;
const int N = 1e3;
long long dp[N+10];
int main()
{
dp[1] = dp[2] = 1;
for(int i = 3; i <= N; i++)
{
for(int j = 1; j <= (i-1)/2; j++)
{
if(j != i-j-1)
dp[i] += dp[j]*dp[i-j-1];
else
dp[i] += dp[j]*(dp[j]+1)/2;
dp[i] %= mod;
}
dp[i]+=dp[i-1];
dp[i] %= mod;
}
int t;
cin >> t;
while(t--)
{
int n;
cin >> n;
cout << dp[n] << endl;
}
return 0;
}
D题
题目描述:Silly_Tape的字符串(Easy_version)
AC代码:
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int MAXN = 2e5+5;
int a[MAXN];
int f[MAXN][21];
int query(int l, int r) {
int k = __lg(r - l + 1);
return max(f[l][k], f[r - (1 << k) + 1][k]);
}
int main() {
int n, m;
cin >> n >> m;
string t;
cin >> t;
t = "$" + t;
string s;
for (auto c : t) s += c, s += '#';
vector<int> d(s.size());
d[1] = 1;
for (int i = 2, l = 0, r = 0; i < s.size(); i++) {
if (i <= r) d[i] = min(d[r - i + l], r - i + 1);
while (s[i - d[i]] == s[i + d[i]]) ++d[i];
if (i + d[i] - 1 > r) l = i - d[i] + 1, r = i + d[i] - 1;
}
int len = 0;
for (int i = 1; i < s.size(); i++) {
if (s[i] != '#') {
a[++len] = (d[i] - 1) / 2 + 1;
}
}
for (int i = 1; i <= n; i++) f[i][0] = a[i];
for (int j = 1; j <= 20; j++) {
for (int i = 1; i <= n - (1 << j) + 1; i++) {
f[i][j] = max(f[i][j - 1], f[i + (1 << (j - 1))][j - 1]);
}
}
while (m--) {
int l, r;
cin >> l >> r;
int left = 0, right = (r - l + 1 + 1) / 2 + 1;
while (left + 1 < right) {
int mid = (left + right) / 2;
if (query(l + mid - 1, r - mid + 1) >= mid) left = mid;
else right = mid;
}
cout << 1LL * left * left << '\n';
}
return 0;
}
E题
题目描述:Silly_Tape的字符串(Hard_version)
AC代码:
#include<bits/stdc++.h>
using namespace std;
vector<int> manacher(std::string s) {
string t = "#";
for (auto c : s) {
t += c;
t += '#';
}
int n = t.size();
vector<int> r(n);
for (int i = 0, j = 0; i < n; i++) {
if (2 * j - i >= 0 && j + r[j] > i) {
r[i] = std::min(r[2 * j - i], j + r[j] - i);
}
while (i - r[i] >= 0 && i + r[i] < n && t[i - r[i]] == t[i + r[i]]) {
r[i] += 1;
}
if (i + r[i] > j + r[j]) {
j = i;
}
}
return r;
}
const int N=2e5+10;
int root[N];
int ptr=0;
struct Seg{
int l,r;
long long val;
}tr[N*50];
int build(int l,int r){
int k=++ptr;
tr[k].val=0;
if(l==r){
return k;
}
int mi=(l+r)>>1;
tr[k].l=build(l,mi);
tr[k].r=build(mi+1,r);
return k;
}
int mif(int fa,int l,int r,int x)
{
int k=++ptr;
tr[k]=tr[fa];
tr[k].val++;
if(l==r){
return k;
}
int mi=(l+r)>>1;
if(x<=mi) tr[k].l=mif(tr[fa].l,l,mi,x);
else tr[k].r=mif(tr[fa].r,mi+1,r,x);
return k;
}
long long qr(int q,int p,int l,int r,int x,int y){
if(l==x&&r==y)
{
return tr[p].val-tr[q].val;
}
int mi=(l+r)>>1;
if(y<=mi) return qr(tr[q].l,tr[p].l,l,mi,x,y);
else if(mi<x) return qr(tr[q].r,tr[p].r,mi+1,r,x,y);
return qr(tr[q].l,tr[p].l,l,mi,x,mi)+qr(tr[q].r,tr[p].r,mi+1,r,mi+1,y);
}
void solve(){
int n,m;
cin>>n>>m;
string s;
cin>>s;
vector<int>ma=manacher(s);
root[0]=build(1,n);
for(int i=1;i<=n;i++){
root[i]=mif(root[i-1],1,n,ma[2*i-1]-1);
}
while(m--)
{
int s,t,x;
cin>>s>>t>>x;
int l=0,r=(t-s)/2;
while(l<r){
int mi=(l+r+1)>>1;
int L=s+mi,R=t-mi;
if(qr(root[L-1],root[R],1,n,mi*2+1,n)>=x) l=mi;
else r=mi-1;
}
auto s1=[&](long long l,long long r,long long d)->long long
{
return d*(l+r)/2;
};
int L=s+l,R=t-l;
if(qr(root[L-1],root[R],1,n,l*2+1,n)<x)
{
cout<<0<<'\n';
continue;
}
cout<<s1(1,l*2+1,l+1)<<'\n';
}
}
int main(){
ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
int t=1;
while(t--){
solve();
}
return 0;
}
F题
题目描述:leetcode
给定一个仅由小写字母构成的字符串 SSS。
对于所有位置 iii,求出 S[i,...,∣S∣] 第一个 leetcode 子序列的终止位置。
AC代码:
#include <bits/stdc++.h>
int res[200005];
using namespace std;
int main()
{
int n;
string s;
s.clear();
cin>>s;
int dp[100];
n = s.length();
for(int i = 1; i <= 50; i++)
{
dp[i] = 0;
}
s = '0' + s;
for(int i = n; i >= 1; i--)
{
if(s[i]=='l')
{
if(dp[2] > i)
{
dp[1] = dp[2];
}
}
else if(s[i]=='e')
{
dp[8] = i;
if(dp[3] > i)
{
dp[2] = dp[3];
}
if(dp[4] > i)
{
dp[3] = dp[4];
}
}
else if(s[i]=='t')
{
if(dp[5] > i)
{
dp[4] = dp[5];
}
}
else if(s[i]=='c')
{
if(dp[6] > i)
{
dp[5] = dp[6];
}
}
else if(s[i]=='o')
{
if(dp[7] > i)
{
dp[6] = dp[7];
}
}
else if(s[i]=='d')
{
if(dp[8] > i)
{
dp[7] = dp[8];
}
}
res[i] = dp[1];
}
for(int i = 1; i <= n; i++){
printf("%d ", res[i]);
}
printf("\n");
return 0;
}