这里会显示出您选择的修订版和当前版本之间的差别。
2020-2021:teams:legal_string:jxm2001:contest:arc_126 [2021/10/09 19:45] jxm2001 创建 |
2020-2021:teams:legal_string:jxm2001:contest:arc_126 [2021/10/09 22:03] (当前版本) jxm2001 |
||
---|---|---|---|
行 85: | 行 85: | ||
</hidden> | </hidden> | ||
+ | ===== E - Infinite Operations ===== | ||
+ | |||
+ | ==== 题意 ==== | ||
+ | |||
+ | 给定一个序列 $A$,定义一次操作为选定两个 $a_i,a_j(a_i\gt a_j)$,将两个数赋值为 $a_i-x,a_j+x$,其中 $0\lt x\le \frac {a_i-a_j}2$,并得到 $x$ 分。 | ||
+ | |||
+ | 定义 $F(A)$ 表示序列 $A$ 经过无限次操作后能得到的最大得分。接下来若干次单点修改操作,每次操作后求 $F(A)$。 | ||
+ | |||
+ | ==== 题解 ==== | ||
+ | |||
+ | 定义势能函数 $G(A)=\sum_{i=1}^n\sum_{j=1}^{i}|a_i-a_j|$,不难发现一次操作得 $x$ 分至少使得 $G(A)$ 减少 $2x$。 | ||
+ | |||
+ | 同时如果假定 $a_1\le a_2\le\cdots a_n$,则选定相邻两个值操作恰好可以得 $x$ 分同时使得 $G(A)$ 减少 $x$。 | ||
+ | |||
+ | 任意取两个相邻数取平均,易知经过无数次操作后有 $G(A)=0$。因此答案为 $\frac {G(A)}2$,树状数组维护答案即可,时间复杂度 $O(n\log n)$。 | ||
+ | |||
+ | <hidden 查看代码> | ||
+ | <code cpp> | ||
+ | const int MAXN=3e5+5,MAXV=6e5+5,mod=998244353,inv2=(mod+1)/2; | ||
+ | int a[MAXN],b[MAXV]; | ||
+ | pair<int,int> opt[MAXN]; | ||
+ | LL c1[MAXV],c2[MAXV]; | ||
+ | #define lowbit(x) ((x)&(-x)) | ||
+ | void update(int pos,int v1,int v2){ | ||
+ | while(pos<MAXV){ | ||
+ | c1[pos]+=v1; | ||
+ | c2[pos]+=v2; | ||
+ | pos+=lowbit(pos); | ||
+ | } | ||
+ | } | ||
+ | pair<LL,LL> query(int pos){ | ||
+ | pair<LL,LL> ans=make_pair(0LL,0LL); | ||
+ | while(pos){ | ||
+ | ans.first+=c1[pos]; | ||
+ | ans.second+=c2[pos]; | ||
+ | pos-=lowbit(pos); | ||
+ | } | ||
+ | return ans; | ||
+ | } | ||
+ | int main() | ||
+ | { | ||
+ | int n=read_int(),q=read_int(); | ||
+ | _rep(i,1,n) | ||
+ | a[i]=b[i]=read_int(); | ||
+ | _rep(i,1,q){ | ||
+ | opt[i].first=read_int(); | ||
+ | opt[i].second=read_int(); | ||
+ | b[n+i]=opt[i].second; | ||
+ | } | ||
+ | sort(b+1,b+n+q+1); | ||
+ | int m=unique(b+1,b+n+q+1)-b; | ||
+ | LL ans=0,sum=0; | ||
+ | _rep(i,1,n){ | ||
+ | int v=lower_bound(b+1,b+m,a[i])-b; | ||
+ | update(v,b[v],1); | ||
+ | sum+=b[v]; | ||
+ | pair<LL,LL> t=query(v); | ||
+ | ans+=1LL*b[v]*t.second-t.first+sum-t.first-1LL*b[v]*(i-t.second); | ||
+ | ans%=mod; | ||
+ | } | ||
+ | _rep(i,1,q){ | ||
+ | int p=opt[i].first; | ||
+ | int v=lower_bound(b+1,b+m,a[p])-b; | ||
+ | pair<LL,LL> t=query(v); | ||
+ | ans-=1LL*b[v]*t.second-t.first+sum-t.first-1LL*b[v]*(n-t.second); | ||
+ | ans%=mod; | ||
+ | update(v,-b[v],-1); | ||
+ | sum-=b[v]; | ||
+ | a[p]=opt[i].second; | ||
+ | v=lower_bound(b+1,b+m,a[p])-b; | ||
+ | update(v,b[v],1); | ||
+ | sum+=b[v]; | ||
+ | t=query(v); | ||
+ | ans+=1LL*b[v]*t.second-t.first+sum-t.first-1LL*b[v]*(n-t.second); | ||
+ | ans%=mod; | ||
+ | enter(1LL*(ans+mod)*inv2%mod); | ||
+ | } | ||
+ | return 0; | ||
+ | } | ||
+ | </code> | ||
+ | </hidden> |