比赛链接
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].tagtreap() {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;
}