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();
}
}

浙公网安备 33010602011771号