非常简单的单点修改+区间加+区间查询。我用的是最近刚学的区间修改版本树状数组。
直接维护即可,注意修改后的单点值已经不是a[i],或者b[i],要通过区间查询求单点。不然是错的。
区间修改版本树状数组:
#include<iostream> #include<string.h> #include<stdio.h> #include<algorithm> #define LL long long using namespace std; LL c_p[400005]; LL sum_p[400005]; LL c_y[400005]; LL sum_y[400005]; LL a[200005]; LL b[200005]; int n,m; int cnt1; int cnt2; int lowbit(int x){ return x&(-x); } void update(int x,int w,LL c[],LL sum[]){ for (int i=x;i<=n;i+=lowbit(i)){ c[i]+=(LL)w; sum[i]+=(LL)w*(x-1); } } LL sum(int x,LL c[],LL sum[]){ LL ans=0; for (int i=x;i>0;i-=lowbit(i)){ ans+=(LL)x*c[i]-sum[i]; } return ans; } int main(){ while(~scanf("%d%d",&n,&m)){ a[0]=0; cnt1=0; cnt2=0; for (int i=1;i<=n;i++){ scanf("%lld",&a[i]); update(i,a[i]-a[i-1],c_p,sum_p); } b[0]=0; for (int i=1;i<=n;i++){ scanf("%lld",&b[i]); update(i,b[i]-b[i-1],c_y,sum_y); } int ss=0; while(m--){ ss++; char op[10]; char to; int x,y,w; scanf("%s",op); if (op[1]==‘i‘){ scanf(" %c",&to); scanf("%d%d",&x,&y); if (to==‘P‘){ int lw=sum(x,c_p,sum_p)-sum(x-1,c_p,sum_p); int rw=sum(y,c_p,sum_p)-sum(y-1,c_p,sum_p); update(x,rw-lw,c_p,sum_p); update(x+1,lw-rw,c_p,sum_p); update(y,lw-rw,c_p,sum_p); update(y+1,rw-lw,c_p,sum_p); }else { int lw=sum(x,c_y,sum_y)-sum(x-1,c_y,sum_y); int rw=sum(y,c_y,sum_y)-sum(y-1,c_y,sum_y); update(x,rw-lw,c_y,sum_y); update(x+1,lw-rw,c_y,sum_y); update(y,lw-rw,c_y,sum_y); update(y+1,rw-lw,c_y,sum_y); } } else if (op[1]==‘u‘){ scanf(" %c",&to); int l,r; scanf("%d%d%d",&l,&r,&w); if (to==‘P‘){ update(l,w,c_p,sum_p); update(r+1,-w,c_p,sum_p); }else { update(l,w,c_y,sum_y); update(r+1,-w,c_y,sum_y); } }else if (op[1]==‘t‘){ scanf(" %c",&to); scanf("%d%d",&x,&y); if (to==‘P‘){ w=sum(x,c_y,sum_y)-sum(x-1,c_y,sum_y); update(x,-w,c_y,sum_y); update(x+1,w,c_y,sum_y); update(y,w,c_p,sum_p); update(y+1,-w,c_p,sum_p); }else { w=sum(x,c_p,sum_p)-sum(x-1,c_p,sum_p); update(x,-w,c_p,sum_p); update(x+1,w,c_p,sum_p); update(y,w,c_y,sum_y); update(y+1,-w,c_y,sum_y); } }else { int l,r; scanf("%d%d",&l,&r); LL num_p=sum(r,c_p,sum_p)-sum(l-1,c_p,sum_p); LL num_y=sum(r,c_y,sum_y)-sum(l-1,c_y,sum_y); if (num_p>num_y){ cnt1++; printf("P %lld\n",num_p); }else { cnt2++; printf("Y %lld\n",num_y); } } } if (cnt1>cnt2){ printf("little P is winner!\n"); }else if (cnt1<cnt2){ printf("little Y is winner!\n"); }else { printf("five five open\n"); } } return 0; }
留坑 :线段树版本:
原文地址:https://www.cnblogs.com/bluefly-hrbust/p/10421243.html
时间: 2024-10-09 00:39:28