代码源挑战赛 Round 47
A
简单题
B
在题目条件下,如果 \(|s| = 1\) 则答案为 \(1\),否则判一下最大的数字。
C
显然可以对于每一位分别考虑,记 \(\operatorname {dist} (x, y)\) 表示 \(x, y\) 在模 \(26\) 意义下的距离,数字串就相当于在 \(0\) 和 \(9\) 之间建立代价为 \(1\) 的传送门。从 \(x\) 到 \(y\) 的最小代价有三种情况:
- 不经过传送门:\(\operatorname {dist} (x, y)\)
- 传送 \(0 \rightarrow 9\):\(\operatorname {dist} (x, 0) + 1 + \operatorname {dist} (9, y)\)
- 传送 \(9 \rightarrow 0\):\(\operatorname {dist} (x, 9) + 1 + \operatorname {dist} (0, y)\)
D
使用 \((n - x + 1) \sim n\) 构造一条点数为 \(x\) 的链,然后把剩余点都接 \(n\) 上就可以了。
E
使用魔法的肯定是一段前缀 + 一段后缀,且长度之和为 \(k\),枚举前缀长度后即可 \(\text O (1)\) 计算,大约是这样写:
int le=min(a[1]+x,a[i+1]),ri=max(a[n]-x,a[n-(k-i)]);
ans=min(ans,max((ri-le+1)/2,0));
F
先处理出所有 \(s _ i\)。考虑 dfs,把所有 \(x\) 的祖先挂到树状数组上,分讨一下正负性。写的时候需要离散化一下。
G
发现这个东西可以用平衡树维护。放一下 FHQ-Treap 代码:
#include<cstdio>
#include<random>
#define N 1200005
using namespace std;
typedef long long ll;
int n,q,a[N];
mt19937 rnd(random_device{}());
struct fhq {
int tot,r;
struct treap {
int lc,rc,cnt,siz,pri;
ll c,val,sum,tag;
#define lc(p) tr[p].lc
#define rc(p) tr[p].rc
#define cnt(p) tr[p].cnt
#define siz(p) tr[p].siz
#define pri(p) tr[p].pri
#define c(p) tr[p].c
#define val(p) tr[p].val
#define sum(p) tr[p].sum
#define tag(p) tr[p].tag
treap() {
pri=rnd();
}
} tr[N];
int node(int u,ll v) {
tot++;
cnt(tot)=siz(tot)=u,c(tot)=v,val(tot)=sum(tot)=u*v;
return tot;
}
void update(int p) {
siz(p)=siz(lc(p))+cnt(p)+siz(rc(p));
sum(p)=sum(lc(p))+val(p)+sum(rc(p));
}
void inc(int p,ll c) {
c(p)+=c,val(p)+=c*cnt(p),sum(p)+=c*siz(p),tag(p)+=c;
}
void spread(int p) {
if(tag(p)) {
if(lc(p)) inc(lc(p),tag(p));
if(rc(p)) inc(rc(p),tag(p));
tag(p)=0;
}
}
void split(int p,int &L,int &R,int k) {
if(!p) {L=R=0; return;}
spread(p);
if(k<=siz(lc(p))) R=p,split(lc(p),L,lc(p),k);
else L=p,split(rc(p),rc(p),R,k-siz(lc(p))-cnt(p));
update(p);
}
int merge(int p,int q) {
if(!p||!q) return p|q;
if(pri(p)<pri(q)) {
spread(p),rc(p)=merge(rc(p),q);
return update(p),p;
} else {
spread(q),lc(q)=merge(p,lc(q));
return update(q),q;
}
}
int ask(int p) {
return rc(p)?ask(rc(p)):cnt(p);
}
void sp(int k) {
int L,R; split(r,L,R,k);
if(siz(L)>k) {
int ss=siz(L)-ask(L),mid; split(L,L,mid,ss);
int sl=k-siz(L),sr=cnt(mid)-sl;
L=merge(L,node(sl,c(mid))),R=merge(node(sr,c(mid)),R);
}
r=merge(L,R);
}
void insert(int k,int c,int v) {
sp(k);
int L,R; split(r,L,R,k);
r=merge(merge(L,node(c,v)),R);
}
ll pop(int k) {
sp(k);
int R; split(r,r,R,k);
return sum(R);
}
void add(int x,int y,ll c) {
sp(x-1),sp(y);
int L,R,mid; split(r,L,R,y),split(L,L,mid,x-1);
inc(mid,c);
r=merge(merge(L,mid),R);
}
ll ask(int x,int y) {
sp(x-1),sp(y);
int L,R,mid; split(r,L,R,y),split(L,L,mid,x-1);
ll res=sum(mid);
r=merge(merge(L,mid),R);
return res;
}
} t1;
int main() {
scanf("%*d%d%d",&n,&q);
for(int i=1,x;i<=n;i++) {
scanf("%d",&x),t1.insert(i-1,1,x);
}
for(int i=1,op,x,y,z;i<=q;i++) {
scanf("%d%d%d",&op,&x,&y);
if(op==1) {
scanf("%d",&z),t1.insert(x,y,z);
printf("%lld\n",t1.pop(n));
}
else if(op==2) {
scanf("%d",&z),t1.add(x,y,z);
}
else {
printf("%lld\n",t1.ask(x,y));
}
}
return 0;
}

浙公网安备 33010602011771号