I Interesting Numbers
解析:简单题,但不会用__int128,代码一直写错
#include<bits/stdc++.h>
using namespace std;
/*
ios::sync_with_stdio(false);
cin.tie(nullptr);
cout.tie(nullptr);
*/
typedef long long LL;
#define int long long
#define ld long double
#define INT __int128
const LL INF = 0x3f3f3f3f3f3f3f3f;
typedef unsigned long long ULL;
typedef pair<long long, long long> PLL;
typedef pair<int, int> PII;
typedef pair<double, double> PDD;
const int inf = 0x3f3f3f3f;
const LL Mod = 998244353;
const ld eps = 1e-12;
const int N = 1e5 + 10, M = 5e5 + 10;
int n;
string L,R;
INT qpow;
void out(INT u){
if(u>=10)out(u/10);
int t=u%10;
cout<<t;
}
INT find(INT u){
INT l=0,r=1e18,ret=l;
while(l<=r){
INT mid=l+(r-l)/2;
if(mid*mid<=u){
ret=mid;
l=mid+1;
}
else{
r=mid-1;
}
}
return ret;
}
INT solve(string s,int t){
INT H=0,L=0;
for(int i=1;i<=s.size();i++){
if(i<=s.size()/2){
H=H*10+s[i-1]-'0';
}
else{
L=L*10+s[i-1]-'0';
}
}
qpow=1;
for(int i=1;i<=n/2;i++){
qpow*=10;
}
if(L<t){
L=qpow-t;
if(H>=t)
H-=t;
}
else{
L-=t;
}
int T=qpow;
qpow=find(qpow);
INT HH=find(H);
INT ll=find(L);
INT ret=0;
if(qpow*qpow>=T)qpow--;
if(HH*HH==H){
ret=(HH)*(qpow+1)+ll+1;
}
else{
ret=(HH+1)*(qpow+1);
}
return ret;
}
signed main(){
ios::sync_with_stdio(false);
cin.tie(nullptr);
cout.tie(nullptr);
cin>>n;
cin>>L>>R;
INT retR=solve(R,0);
INT retL=solve(L,1);
out(retR-retL);
return 0;
}
/*
4
2345 5678
58
100000000000000000000000000000000000000000000000000000000 9000000000000000000000000000000000000000000000000000000000
10
1000000000 9000000000
6
100000 999999
2
9 99
2
10 99
*/
B Break Sequence
解析:线段树优化dp
很容易看出来本题需要使用dp算法,f[i]:表示钱 i 个元素的划分方案。
直接转移的时间复杂度是O(n*n*m)
优化:由于m很小,因此可以对 S 进行扫描,可以发现对于某个值 x 而言,会是其不合法的区间只有一个,区间左端点在从当前位置往左数第 j+1 个 x 的位置,区间右端点在从当前位置往左数第 j 个 x 的位置-1 的位置,对于不合法的区间,可以用线段树进行维护。
(本题对不合法区间的维护的思想与此D题很像:Codeforces Round 965 (Div. 2)-优快云博客)
#include <iostream>
#include <string>
#include <cstring>
#include <cmath>
#include <ctime>
#include <algorithm>
#include <utility>
#include <stack>
#include <queue>
#include <vector>
#include <set>
#include <math.h>
#include <map>
#include <sstream>
#include <deque>
#include <unordered_map>
#include <unordered_set>
#include <bitset>
#include <stdio.h>
#include <tuple>
using namespace std;
/*
ios::sync_with_stdio(false);
cin.tie(nullptr);
cout.tie(nullptr);
*/
typedef long long LL;
#define int long long
#define ld long double
//#define INT __int128
const LL INF = 0x3f3f3f3f3f3f3f3f;
typedef unsigned long long ULL;
typedef pair<long long, long long> PLL;
typedef pair<int, int> PII;
typedef pair<double, double> PDD;
const int inf = 0x3f3f3f3f;
const LL mod = 998244353;
const ld eps = 1e-12;
const int N = 2e5 + 10, M = 5e5 + 10;
int n, m;
int A[N], f[N];
vector<int>v[N];
struct TREE {
int tg;
int v, sum;
}tr[N<<2];
#define ls u<<1
#define rs u<<1|1
void up(int u) {
tr[u].v = min(tr[ls].v, tr[rs].v);
tr[u].sum = 0;
if (tr[u].v == tr[ls].v)tr[u].sum += tr[ls].sum, tr[u].sum %= mod;
if (tr[u].v == tr[rs].v)tr[u].sum += tr[rs].sum, tr[u].sum %= mod;
}
void down(int u) {
if (tr[u].tg) {
tr[ls].tg += tr[u].tg;
tr[ls].v += tr[u].tg;
tr[rs].tg += tr[u].tg;
tr[rs].v += tr[u].tg;
tr[u].tg = 0;
}
}
void add(int l, int r, int u, int ql, int qr, int d) {
if (ql <= l && r <= qr) {
tr[u].sum = d;
return;
}
down(u);
int mid = l + r >> 1;
if (ql <= mid)add(l, mid, ls, ql, qr, d);
if (qr > mid)add(mid + 1, r, rs, ql, qr, d);
up(u);
}
void modify(int l, int r, int u, int ql, int qr, int d) {
if (ql <= l && r <= qr) {
tr[u].v += d;
tr[u].tg += d;
//cout << "_+++++++++++" << l << " " << r << " " << tr[u].v << endl;
return;
}
down(u);
int mid = l + r >> 1;
if (ql <= mid)modify(l, mid, ls, ql, qr, d);
if (qr > mid)modify(mid + 1, r, rs, ql, qr, d);
up(u);
}
signed main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
cout.tie(nullptr);
cin >> n >> m;
for (int i = 1; i <= n; i++) {
cin >> A[i];
}
vector<int>s;
s.reserve(m + 2);
for (int i = 1; i <= m; i++) {
int a;
cin >> a;
s.push_back(a);
}
add(0, n, 1, 0, 0, 1);
for (int i = 1; i <= n; i++) {
for (int j : s) {
if (j < v[A[i]].size()) {
modify(0, n, 1, v[A[i]][v[A[i]].size() - j - 1], v[A[i]][v[A[i]].size() - j] - 1, -1);
//cout << "++++++++++++++++++" << v[A[i]][v[A[i]].size() - j - 1] << " " << v[A[i]][v[A[i]].size() - j] - 1 << endl;
}
else if (j == v[A[i]].size()) {
modify(0, n, 1, 0, v[A[i]][v[A[i]].size() - j] - 1, -1);
//cout << "++++++++++++++++++" << 0 << " " << v[A[i]][v[A[i]].size() - j] - 1 << endl;
}
}
v[A[i]].push_back(i);
for (int j : s) {
if (j < v[A[i]].size()) {
modify(0, n, 1, v[A[i]][v[A[i]].size() - j - 1], v[A[i]][v[A[i]].size() - j] - 1, 1);
//cout << "___________________" << v[A[i]][v[A[i]].size() - j - 1] << " " << v[A[i]][v[A[i]].size() - j] - 1 << endl;
}
else if (j == v[A[i]].size()) {
modify(0, n, 1, 0, v[A[i]][v[A[i]].size() - j] - 1, 1);
//cout << "___________________" << 0 << " " << v[A[i]][v[A[i]].size() - j] - 1 << endl;
}
}
f[i] = tr[1].sum;
//cout << "=========================_" << f[i] << " " << i <<" "<<tr[1].v<< endl;
add(0, n, 1, i, i, f[i]);
}
cout << f[n] << endl;
return 0;
}
/*
3 1
1 1 1
1
6 1
6 1 2 3 1 3
2
25 2
2 1 1 3 5 1 4 3 3 1 1 1 4 5 3 4 4 3 2 3 5 2 1 3 1
5 4
*/