D - Progressions Covering
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define int long long
const int N=3e5+10;
struct node{int l,r,val,lazy;}tr[N<<2];
int n,a[N],k;
void pushup(int p){tr[p].val=tr[p<<1].val+tr[p<<1|1].val;}
void pushdown(int p){
if(tr[p].lazy==0) return ;
tr[p<<1].val+=(tr[p<<1].r-tr[p<<1].l+1)*tr[p].lazy;tr[p<<1].lazy+=tr[p].lazy;
tr[p<<1|1].val+=(tr[p<<1|1].r-tr[p<<1|1].l+1)*tr[p].lazy;tr[p<<1|1].lazy+=tr[p].lazy;
tr[p].lazy=0;
}
void build(int l,int r,int p){
tr[p].l=l;tr[p].r=r;
if(l==r){tr[p].val=a[l]-a[l-1];return ;}
int mid=l+r>>1;
build(l,mid,p<<1);
build(mid+1,r,p<<1|1);
pushup(p);
}
void change(int l,int r,int p,int val){
if(tr[p].l>=l&&tr[p].r<=r){tr[p].lazy+=val;tr[p].val+=(tr[p].r-tr[p].l+1)*val;return ;}
pushdown(p);
int mid=tr[p].l+tr[p].r>>1;
if(mid>=l) change(l,r,p<<1,val);
if(mid+1<=r) change(l,r,p<<1|1,val);
pushup(p);
}
int query(int l,int r,int p){
if(tr[p].l>=l&&tr[p].r<=r) return tr[p].val;
pushdown(p);
int mid=tr[p].l+tr[p].r>>1;
int res=0;
if(mid>=l) res+=query(l,r,p<<1);
if(mid+1<=r) res+=query(l,r,p<<1|1);
return res;
}
int32_t main(){
int t=1;
while(t--){
scanf("%lld%lld",&n,&k);for(int i=1;i<=n;i++) scanf("%lld",&a[i]);
build(1,n,1);
int res=0;
for(int i=n;i>=1;i--){
int now=query(1,i,1);
if(now<=0) continue;
int K=min(k,i);
int nd=(now+K-1)/K;
res+=nd;
change(i-k+1,i,1,-nd);
}
cout<<res<<endl;
}
}
C - Water the Trees
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define int long long
const int N=3e5+10;
int t,n,h[N];
int cnt[3];
int run2(int nd1,int nd2){
int ans=min(nd1,nd2)*2;
if(nd1>nd2) ans+=(nd1-nd2)*2;
if(nd2>nd1) ans+=(nd2-nd1)*2-1;
return ans;
}
int run(int x){
memset(cnt,0,sizeof cnt);
int sum=0;
for(int i=1;i<=n;i++) cnt[2]+=(x-h[i])/2,sum+=(x-h[i]);
int ans=1e18;
if(cnt[2]>=sum-cnt[2]*2){
int nd1=sum/3,nd2=sum-nd1*2;
ans=min(run2(nd1,nd2),ans);
if(nd2>=2) ans=min(run2(nd1+1,nd2-2),ans);
}else{
ans=cnt[2]*2;
ans+=(sum-cnt[2]*3)*2-1;
}
return ans;
}
int32_t main(){
scanf("%lld",&t);
while(t--){
scanf("%lld",&n);
int maxn=0;
for(int i=1;i<=n;i++) scanf("%lld",&h[i]),maxn=max(maxn,h[i]);
int res=1e18;
for(int i=maxn;i<=maxn+3;i++) res=min(res,run(i));
cout<<res<<endl;
}
}
B. Getting Zero
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=2e5+10;
const int mod=32768;
int n,a[N],vis[N],dis[N];
void bfs(int x){
memset(dis,0x3f,sizeof dis);
dis[x]=0;
queue<int> q;
q.push(x);
while(q.size()){
auto tp=q.front();q.pop();
set<int> s;
int nxt=(tp-1+mod)%mod;
s.insert(nxt);
if(tp%2==0) s.insert((tp/2));
s.insert(((tp+mod)/2));
for(auto it:s){
if(dis[it]>dis[tp]+1){
dis[it]=dis[tp]+1;
q.push(it);
}
}
}
}
int main(){
bfs(mod);
dis[0]=0;
cin>>n;for(int i=1;i<=n;i++){
int x;cin>>x;
cout<<dis[x]<<" ";
}cout<<endl;
}