AtCoder Beginner Contest 426

D - Pop and Insert

最大的相同段,从两边找,相同就翻转两次丢进去,不同就翻转了丢进去

#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


int n;
int work(string s){
int cnt = 0; int mx = 0; int st,ed;
int l = 0; int r = 0;
    for(int i = 1; i <= n; i ++){
		if(s[i] == '0') {
			r = i;
			cnt ++;
			if(mx < cnt){
				mx = cnt;
				st = l; ed = r; 
			}
		}
		else {
			cnt = 0; 
			l = i + 1; r = l;
		}
    }
	if(mx == n) return 0;

	int ret = 0;
	for(int i = st - 1; i >= 1; i --){
		if(s[i] == s[st]) ret += 2;
		else ret ++;
	}
	for(int i = ed + 1; i <= n; i ++){
		if(s[i] == s[ed]) ret += 2;
		else ret ++;
	}
	return ret;
}

void solve(){
    cin >> n; string s; cin >> s; s = "a" + s;

	int ans = work(s);
	for(int i = 1; i <= n; i ++){
		s[i] ^= 1;
	}
	ans = min(ans, work(s));

	cout << ans << '\n';
}

signed main(){
    std::ios::sync_with_stdio(false);
    int T = 1; cin >> T;
    while(T--){
        solve();
    }
}

E - Closest Moment

开long double
设出时间,移动过程中最多只会出现一个峰
一个到达后,另一个移动,这个也可能出现一个峰
分这两段三分

#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 ld long double
#define pb push_back
#define ft first
#define se second
#define inf 0x3f3f3f3f
#define INF 0x3f3f3f3f3f3f3f3f


#define int long long


ld tsx, tsy, tgx, tgy, asx, asy, agx, agy, len1, len2;
ld get(ld t){
	ld x1 = tsx + t*(tgx - tsx)/len1; ld y1 = tsy + t*(tgy - tsy)/len1;
	ld x2 = asx + t*(agx - asx)/len2; ld y2 = asy + t*(agy - asy)/len2;
	return (x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2);
}
ld get2(ld t){
	ld x1 = tgx; ld y1 = tgy;
		ld x2 = asx + t*(agx - asx)/len2; ld y2 = asy + t*(agy - asy)/len2;
	return (x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2);
}

void solve(){
    
    cin >> tsx >> tsy >> tgx >> tgy >> asx >> asy >> agx >> agy;
    len1 = sqrtl((tgx - tsx) *(tgx - tsx) + (tgy - tsy) * (tgy - tsy));
    len2 = sqrtl((agx - asx) *(agx - asx) + (agy - asy) * (agy - asy));
    if((tgx - tsx) *(tgx - tsx) + (tgy - tsy) * (tgy - tsy) > (agx - asx) *(agx - asx) + (agy - asy) * (agy - asy)) {
      swap(tsx, asx); swap(tsy, asy); swap(tgx, agx); swap(tgy, agy);
      swap(len1, len2);
    }
    
    ld l = 0; ld r = len1;
    while(r - l > 1e-8){
      ld midl = (2*l + r) / 3;
		ld midr = (l + 2*r) / 3;
		if(get(midr) < get(midl)) l = midl;
		else r = midr;
    }
	ld ans = get(l);
	
	l = len1; r = len2;
	while(r - l > 1e-8){
		ld midl = (2*l + r) / 3;
		ld midr = (l + 2*r) / 3;
		if(get2(midr) < get2(midl)) l = midl;
		else r = midr;
	}
	ans = min(ans, get2(l));
	
	cout << fixed << setprecision(7) << sqrtl(ans) << '\n';
}

signed main(){
    std::ios::sync_with_stdio(false);
    int T = 1; cin >> T;
    while(T--){
        solve();
    }
}

F - Clearance

值得积累relu
记录区间mn,非0个数
当区间mn>k时,直接获得,区间修改-=k O(qlogn)
当区间存在<=k的时候,就继续往下特殊处理这个点
每个只会被特殊处理一次,单点修改的时间复杂度能保证O(nlogn)

#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 = 300010;
ll a[N];

# define ls(u) u<<1
# define rs(u) u<<1|1
struct Tree{
    int l, r;
ll mn; int cnt;
    ll add;
}tr[4*N];

void pushdown(int u){
    if(tr[u].add){
        tr[ls(u)].mn += tr[u].add;
        tr[ls(u)].add += tr[u].add;
        
        tr[rs(u)].mn += tr[u].add;
        tr[rs(u)].add += tr[u].add;

        tr[u].add = 0;
    }
}
void pushup(int u){
    tr[u].mn = min(tr[ls(u)].mn, tr[rs(u)].mn);
    tr[u].cnt = tr[ls(u)].cnt + tr[rs(u)].cnt;
}

void bui(int u, int l, int r){
    tr[u] = {l, r, a[l], 1, 0};
    if(l == r){
        return ;
    }
    int mid = (l + r) >> 1;
    bui(u*2, l, mid);
    bui(u*2 + 1, mid + 1, r);
    pushup(u);
}

ll modify(int u, int x, int y, ll k){
    if(tr[u].cnt == 0) return 0;
    if(x <= tr[u].l && tr[u].r <= y && tr[u].mn > k){
        tr[u].mn -= k; tr[u].add -= k;
        return k * tr[u].cnt;
    }
    if(tr[u].l == tr[u].r){ 
        ll  _ = tr[u].mn;
        tr[u].mn = INF; tr[u].cnt = 0;
        return _;
    }
    int mid = (tr[u].l + tr[u].r) >> 1; ll ret = 0;
    pushdown(u);
    if(x <= mid) ret += modify(u*2, x, y, k);
    if(y >= mid + 1) ret += modify(u*2 + 1, x, y, k);
    pushup(u);
    return ret;
}

void solve(){
    int n; cin >> n;
    for(int i = 1; i <= n; i ++) cin >> a[i];
    bui(1, 1, n);
    int q; cin >> q;
    while(q --){
        int x, y; ll k; cin >> x >> y >> k;
        cout << modify(1, x, y, k) << '\n';
    }
    
}

signed main(){
    std::ios::sync_with_stdio(false);
    int T = 1; //cin >> T;
    while(T--){
        solve();
    }
}
posted @ 2025-12-24 14:23  arin876  阅读(7)  评论(0)    收藏  举报