AtCoder Beginner Contest 428
D - 183184
非常好的推式子
被at卡sqrt了
#include<bits/stdc++.h>
using namespace std;
#define endl '\n'
#define yes cout << "Yes" << endl
#define no cout << "No" << endl
#define pii pair<int,int>
#define ll long long
#define pb push_back
#define ft first
#define se second
#define inf 0x3f3f3f3f
#define INF 0x3f3f3f3f3f3f3f3f
#define int long long
using i128 = __int128;
using ull = unsigned long long;
int pp[20];
int qp(int a, int b){
return pp[b];
}
int get(int x){
int len = 0;
while(x){
len ++; x /= 10;
}
return len;
}
ll Sqrt1(ull x){//开根下取整
ll l = 0, r = 1e10;
while(l < r){
ll mid = (l + r) >> 1;
(i128)mid * mid >= x ? r = mid : l = mid + 1;
}
return l;
}
ll Sqrt2(ull x){//开根上取整
ll l = 0, r = 1e10;
while(l < r){
ll mid = (l + r + 1) >> 1;
(i128)mid * mid <= x ? l = mid : r = mid - 1;
}
return l;
}
void solve(){
int c, d; cin >> c >> d;
int ans = 0;
for(int len = get(c + 1); len <= get(c + d); len ++ ){
int r = min(d, qp(10, len) - 1 - c) + c * (qp(10, len) + 1);
int l = max(1ll, qp(10, len - 1) - c) + c * (qp(10, len) + 1);
r = Sqrt2(r);//r = floor(sqrt(r));
l = Sqrt1(l);//l = ceil(sqrt(l));
ans += r - l + 1;
// ans += floor(sqrt(r)) - ceil(sqrt(l)) + 1;
}
cout << ans << '\n';
}
signed main(){
std::ios::sync_with_stdio(false);
pp[0] = 1;
for(int i = 1; i <= 18; i ++) pp[i] = pp[i - 1] * 10;
int T = 1; cin >> T;
while(T--){
solve();
}
}
E - Farthest Vertex
简单扯直径题
#include<bits/stdc++.h>
using namespace std;
#define endl '\n'
#define yes cout << "Yes" << endl
#define no cout << "No" << endl
#define pii pair<int,int>
#define ll long long
#define pb push_back
#define ft first
#define se second
#define inf 0x3f3f3f3f
#define INF 0x3f3f3f3f3f3f3f3f
#define int long long
const int N = 500010;
vector<int> G[N];
int dep[N]; int mx = 0;
int pre[N];
bool vis[N];
int ans[N];
void dfs1(int u, int fa){
dep[u] = dep[fa] + 1;
if(dep[u] > dep[mx] ||(dep[u] == dep[mx] && u > mx)){
mx = u;
}
for(auto v:G[u]){
if(v == fa) continue;
dfs1(v,u);
}
}
void dfs2(int u, int fa){
pre[u] = fa;
dep[u] = dep[fa] + 1;
if(dep[u] > dep[mx]||(dep[u] == dep[mx] && u > mx)){
mx = u;
}
for(auto v:G[u]){
if(v == fa) continue;
dfs2(v, u);
}
}
void dfs3(int u, int fa, int x){
ans[u] = x;
for(auto v:G[u]){
if(v == fa) continue;
if(vis[v]) continue;
dfs3(v, u, x);
}
}
void solve(){
int n; cin >> n;
for(int i = 1; i <= n - 1; i ++){
int u, v; cin >> u >> v; G[u].pb(v); G[v].pb(u);
}
dfs1(1, 0);
int st = mx; mx = 0;
dfs2(st, 0);
int ed = mx;
vector<int> vec;
int tmp = ed; while(tmp) {
vis[tmp] = 1;
vec.pb(tmp); tmp = pre[tmp];
}
if(ed > st) reverse(vec.begin(), vec.end());
for(int i = 0; i < vec.size(); i ++){
int x = (i > (int)vec.size() - i - 1)? vec[0] : vec.back();
dfs3(vec[i], 0, x);
}
for(int i = 1; i <= n; i ++){
cout << ans[i] << '\n';
}
}
signed main(){
std::ios::sync_with_stdio(false);
int T = 1; //cin >> T;
while(T--){
solve();
}
}
F - Pyramid Alignment
发现x+1/2被一个区间i包含,必然被i+1包含,这样包含他的区间就是一个[i,n]的后缀,二分
线段树存上次左端还是右端对齐,以及对齐位置
#include<bits/stdc++.h>
using namespace std;
#define endl '\n'
#define yes cout << "Yes" << endl
#define no cout << "No" << endl
#define pii pair<int,int>
#define ll long long
#define pb push_back
#define ft first
#define se second
#define inf 0x3f3f3f3f
#define INF 0x3f3f3f3f3f3f3f3f
#define int long long
const int N = 200010;
int n;
int w[N];
struct Tree{
int l, r;
int k, lst;
int ka, lsta;
}tr[4*N];
void pushup(Tree& u, Tree& l, Tree& r){
if(l.k == r.k && l.lst == r.lst){
u.k = l.k;
u.lst = l.lst;
}else {
u.k = -1;
u.lst = -1;
}
}
void pushup(int u){
pushup(tr[u], tr[u << 1], tr[u << 1 | 1]);
}
void pushdown(Tree& u, Tree& l, Tree & r){
if(u.ka != -1){
l.k = u.k;
l.lst = u.lst;
l.ka = u.ka;
l.lsta = u.lsta;
r.k = u.k;
r.lst = u.lst;
r.ka = u.ka;
r.lst = u.lst;
u.ka = -1;
u.lst = -1;
}
}
void pushdown(int u){
pushdown(tr[u], tr[u << 1], tr[u << 1 | 1]);
}
void bui(int u, int l, int r){
tr[u] = {l, r, 0, 0, -1, -1};
if(l == r){
return ;
}
int mid = (tr[u].l + tr[u].r) >> 1;
bui(u*2, l, mid);
bui(u*2 + 1, mid + 1, r);
pushup(u);
}
pii query(int u, int x){
if(tr[u].l == x && tr[u].r == x){
return {tr[u].k, tr[u].lst};
}
int mid = (tr[u].l + tr[u].r) >> 1;
pushdown(u);
if(x <= mid) return query(u << 1, x);
else return query(u << 1 | 1, x);
}
void modify(int u, int x, int y, int k, int lst){
if(x <= tr[u].l && tr[u].r <= y){
tr[u].k = k; tr[u].lst = lst;
tr[u].ka = k; tr[u].lsta = lst;
return ;
}
pushdown(u);////
int mid = (tr[u].l + tr[u].r) >> 1;
if(x <= mid) modify(u << 1, x, y, k, lst);
if(y >= mid + 1) modify(u << 1 | 1, x, y, k, lst);
pushup(u);
}
bool ck(int mid, int x){
auto [k, lst] = query(1, mid);
int l, r;
if(!k){
l = lst; r = lst + w[mid];
}else {
l = lst - w[mid]; r = lst;
}
return (x >= l) && (x < r);
}
void solve(){
cin >> n;
for(int i = 1; i <= n; i ++) cin >> w[i];
bui(1, 1, n);
// for(int i = 1; i <= n; i ++){
// cout << tr[i].l << ' ' << tr[i].r << '\n';
// }
int q; cin >> q;
while(q --){
int op, v, x; cin >> op;
if(op == 1){
cin >> v;
auto [k,lst] = query(1, v);//上一次对齐左/右端点
if(k) lst = lst - w[v];
modify(1, 1, v, 0, lst);
}else if(op == 2){
cin >> v;
auto [k,lst] = query(1, v);//上一次对齐左/右端点
if(!k) lst = lst + w[v];
modify(1, 1, v, 1, lst);
}
else {
cin >> x;
int l = 1; int r = n;
while(l < r){
int mid = (l + r) >> 1;
if(ck(mid, x)) r = mid;
else l = mid + 1;
}
if(ck(l, x)){
cout << n - l + 1 << '\n';
}else cout << 0 << '\n';
}
}
}
signed main(){
std::ios::sync_with_stdio(false);
int T = 1;// cin >> T;
while(T--){
solve();
}
}

浙公网安备 33010602011771号