比赛链接:比赛详情 - ZYZ28-NOIP模拟赛-Round4 - ZYZOJ
写作背景
霜刃初试未轻狂,云路千层始此航。静夜码文星作伴,秋闱析理叶承光。
浅才恰似萤灯小,韧志能穿石壁长。待得春风融冻土,新芽破土向朝阳。
----DeepSeek
A.speed
提交链接:题目详情 - 04-A - ZYZOJ
题面

分析
一眼最小生成树,难道是题意理解错了?我不理解,但是调试代码的能力还是太底下了 ,需要沉下心来,继续努力,和shy一起去THU!好吧,再也不熬夜了,居然写了+=0x3f3f3f3f这样的神秘代码。总之,思路理解了,还是代码能力。
正解
cpp
#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N = 200005;
int n, m, k;
struct node{
int u, v, w;
}e[N];
bool cmp(node x, node y){
return x.w < y.w;
}
int fa[N];
int find(int x){
return x == fa[x] ? fa[x] : fa[x] = find(fa[x]);
}
signed main(){
freopen("speed.in", "r", stdin);
freopen("speed.out", "w", stdout);
cin >> n >> m >> k;
int tmp = 0x3f3f3f3f3f3f3f3f;
for (int i = 1; i <= m; i++){
cin >> e[i].u >> e[i].v >> e[i].w;
tmp = min(tmp, abs(e[i].w - k));
}
sort(e + 1, e + m + 1, cmp);
for (int i = 1; i <= n; i++)
fa[i] = i;
int ans = 0;
for (int i = 1; i <= m; i++){
if (find(e[i].u) == find(e[i].v))
continue;
fa[find(e[i].u)] = find(e[i].v);
if (e[i].w > k)
ans += e[i].w - k;
}
ans = max(ans, tmp);
cout << ans;
}
B.drunkard
提交链接:题目详情 - 04-B - ZYZOJ
题面

分析






别问我代码在哪,我也不会写。
C.peak
提交链接:题目详情 - 04-C - ZYZOJ
题面

分析
场上写了暴力,也知道其中一个r-l+1的subtask,但是没交,保了rating。



好吧,我菜炸了。
正解
cpp
#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N=200010;
int n,a[N],q;
struct node{
int l,r,f,mk;
}nodes[N<<2];
node merge(node x,node y){
if(!x.l) return y;
node z;z.l=x.l,z.r=y.r;
z.f=(x.f==y.f?x.f:0);
z.mk=((x.mk&&y.f==2)||(x.f==1&&y.mk)||(x.f==1&&y.f==2));
return z;
}
int get(int x){
return (x?(x>0?1:2):3);//1->+ 2->- 3->0
}
void pushup(int p){
nodes[p]=merge(nodes[p<<1],nodes[p<<1|1]);
}
void build(int p,int l,int r){
nodes[p]=(node){l,r,0,0};
if(l==r){
nodes[p].f=get(a[l]);
return;
}
int mid=l+r>>1;
build(p<<1,l,mid);
build(p<<1|1,mid+1,r);
pushup(p);
}
void update(int p,int pos,int v){
if(nodes[p].l==nodes[p].r){
nodes[p].f=v;
return;
}
int mid=nodes[p].l+nodes[p].r>>1;
if(pos<=mid) update(p<<1,pos,v);
else update(p<<1|1,pos,v);
pushup(p);
}
node query(int p,int l,int r){
if(nodes[p].l>=l&&nodes[p].r<=r) return nodes[p];
int mid=nodes[p].l+nodes[p].r>>1;node sum={0,0,0,0};
if(l<=mid) sum=merge(sum,query(p<<1,l,r));
if(r>mid) sum=merge(sum,query(p<<1|1,l,r));
return sum;
}
signed main(){
freopen("peak.in","r",stdin);
freopen("peak.out","w",stdout);
ios::sync_with_stdio(0);
cin.tie(0),cout.tie(0);
cin>>n;
for(int i=1;i<=n;i++) cin>>a[i];
for(int i=n;i>=1;i--) a[i]=a[i]-a[i-1];
build(1,1,n);
cin>>q;
while(q--){
int op,l,r,x;
cin>>op>>l>>r;
if(op==1){
cin>>x;
a[l]+=x,a[r+1]-=x;
update(1,l,get(a[l]));
if(r+1<=n) update(1,r+1,get(a[r+1]));
}
else if(op==2){
if(l==r){
cout<<"1\n";
continue;
}
node k=query(1,l+1,r);
cout<<(k.f==3)<<"\n";
}
else if(op==3){
if(l==r){
cout<<"1\n";
continue;
}
node k=query(1,l+1,r);
cout<<(k.f==1)<<"\n";
}
else if(op==4){
if(l==r){
cout<<"1\n";
continue;
}
node k=query(1,l+1,r);
cout<<(k.f==2)<<"\n";
}
else cout<<query(1,l+1,r).mk<<"\n";
}
return 0;
}
D.selection
提交链接:题目详情 - 04-D - ZYZOJ
题面

分析



STD
cpp
#include<bits/stdc++.h>
#define LL long long
#define max(a,b) ((a)>(b)?(a):(b))
#define min(a,b) ((a)<(b)?(a):(b))
inline int read() {
char c=getchar();int x=0;while(c<'0'||c>'9')c=getchar();
while(c>='0'&&c<='9')x=(x<<3)+(x<<1)+c-48,c=getchar();return x;
}
const int mod=998244353,maxn=100005;
struct sode{int l,r,v;}st[maxn],bl[maxn];
struct node{int l,r,x,v;}A[maxn*30],B[maxn*30];
struct Seg{int l,r,v;}seg[2][maxn];
int gcd(int a,int b) {return !b?a:gcd(b,a%b);}
inline int dqm(int x) {return x<0?x+mod:x;}
inline int qm(int x) {return x>=mod?x-mod:x;}
inline int cmp(const node &A,const node &B){
return A.v==B.v?A.x<B.x:A.v<B.v;
}
inline int ctp(const node &A,const node &B) {
return A.v==B.v?A.x>B.x:A.v<B.v;
}
int n,a[maxn],top,sa,sb,lp,sz[2],ans,pre[maxn];
int l[maxn*3],r[maxn*3],tag[maxn*3],d[maxn*3];
inline void pushup(int i) {d[i]=qm(d[i<<1]+d[i<<1|1]);}
inline void pushr(int i,int v) {
tag[i]=v;d[i]=1ll*(r[i]-l[i]+1)*v%mod;
}
inline void pushdown(int i) {
if(tag[i]==-1) return;pushr(i<<1,tag[i]);
pushr(i<<1|1,tag[i]);tag[i]=-1;
}
void bud(int x,int y,int i) {
l[i]=x,r[i]=y,tag[i]=-1;if(x==y) return;
int mid=x+y>>1;bud(x,mid,i<<1),bud(mid+1,y,i<<1|1);
}
void chg(int x,int y,int v,int i) {
if(x<=l[i]&&y>=r[i]) {pushr(i,v);return;}
int mid=l[i]+r[i]>>1;pushdown(i);
if(x<=mid) chg(x,y,v,i<<1);
if(y>mid) chg(x,y,v,i<<1|1);pushup(i);
}
int qry(int x,int y,int i) {
if(x<=l[i]&&y>=r[i]) return d[i];
int mid=l[i]+r[i]>>1;pushdown(i);
return qm((x<=mid?qry(x,y,i<<1):0)+(y>mid?qry(x,y,i<<1|1):0));
}
inline void ins(int l,int r,int v,int o) {
if(r>n)r=n;if(l<1)l=1;if(l>r) return;
seg[o][++sz[o]]=(Seg){l,r,v};
}
inline void calc(int l,int r,int v) {
pre[l]=qm(pre[l]+v),pre[r+1]=dqm(pre[r+1]-v);
}
inline void solve(int L,int R) {
int lst=0,v=0;sz[0]=sz[1]=0;
for(int i=L;i<=R;++i) {
chg(lst,A[i].x-1,v,1);
ins(lst+1,A[i].x,qm(v+1),0);
lst=A[i].x;
v=qm(v+qry(A[i].l-1,A[i].r-1,1));
v=qm(v+A[i].r-A[i].l+1);
}
chg(lst,n,v,1);
ins(lst+1,n+1,qm(v+1),0);
lst=n+1,v=0;int rp=lp;
while(lp<=sb&&B[lp].v==A[L].v) ++lp;
for(int i=rp;i<lp;++i) {
chg(B[i].x+1,lst,v,1);
ins(B[i].x,lst-1,qm(v+1),1);
lst=B[i].x;
v=qm(v+qry(B[i].l+1,B[i].r+1,1));
v=qm(v+B[i].r-B[i].l+1);
}
chg(1,lst,v,1);ans=qm(ans+v);
ins(0,lst-1,qm(v+1),1);
std::reverse(seg[1],seg[1]+sz[1]+1);
int x,y;x=0,y=0;
while(x<=sz[0]&&y<=sz[1]) {
calc(max(seg[0][x].l,seg[1][y].l),min(seg[0][x].r,seg[1][y].r),dqm(1ll*seg[0][x].v*seg[1][y].v%mod-1));
if(seg[0][x].r<seg[1][y].r) ++x;
else if(seg[0][x].r>seg[1][y].r) ++y;
else if(seg[0][x].r==seg[1][y].r) ++y,++x;
}
}
int main() {
freopen("selection.in", "r", stdin);
freopen("selection.out", "w", stdout);
n=read();
for(int i=1;i<=n;i++) a[i]=read();
for(int i=1;i<=n;i++) {
for(int j=1;j<=top;++j)
st[j].v=gcd(st[j].v,a[i]);
st[++top]=(sode){i,i,a[i]};
int tot=0,x=i,y=i;
for(int j=top-1;j>=0;--j) {
if(st[j].v!=st[j+1].v) {
bl[++tot].l=x,bl[tot].r=y;
bl[tot].v=st[j+1].v;
x=st[j].l,y=st[j].r;
}else x=st[j].l;
}
top=0;
while(tot) st[++top]=bl[tot--];
for(int j=1;j<=top;++j)
A[++sa]=(node){st[j].l,st[j].r,i,st[j].v};
}
top=0;
for(int i=n;i;i--) {
for(int j=1;j<=top;++j)
st[j].v=gcd(st[j].v,a[i]);
st[++top]=(sode){i,i,a[i]};
int tot=0,x=i,y=i;
for(int j=top-1;j>=0;--j)
if(st[j].v!=st[j+1].v) {
bl[++tot].l=x,bl[tot].r=y;
bl[tot].v=st[j+1].v;
x=st[j].l,y=st[j].r;
} else y=st[j].r;
top=0;
while(tot) st[++top]=bl[tot--];
for(int j=1;j<=top;++j)
B[++sb]=(node){st[j].l,st[j].r,i,st[j].v};
}
std::sort(A+1,A+sa+1,cmp);std::sort(B+1,B+sb+1,ctp);
int L=1;lp=1;
bud(0,n+1,1);
for(int i=2;i<=sa+1;++i)
if(A[i].v!=A[i-1].v)
solve(L,i-1),L=i;
for(int i=1;i<=n;i++)pre[i]=qm(pre[i-1]+pre[i]);
for(int i=1;i<=n;i++)printf("%d ",dqm(ans-pre[i]));
return 0;
}