今天又是自己被虐的一天
今天难度大概是省选难度-,noip+
x姓巨佬100+0+20
g姓巨佬100+10+0
窝:60+10+0
又被爆踩了。。。
先放题面吧
t1的话就是一个权值树状数组,先进行问题转化,将T从小到大排序,问题就成了sum(l)-n*t1-(n-1)*t2...1*tn
然后可以用线段树,权值树状数组,splay等维护
code:
#include<bits/stdc++.h> #define re register #define inc(i,j,k) for(re int i=j;i<=k;++i) #define ll long long using namespace std; const int maxn=200010; inline int read() { re int x=0,f=1; char ch=getchar(); while(ch<‘0‘||ch>‘9‘) {if(ch==‘-‘) f=-1; ch=getchar();} while(ch>=‘0‘&&ch<=‘9‘) {x=x*10+(ch^48); ch=getchar();} return x*f; } int n,m,L[maxn],T[maxn],tmp[maxn]; ll ans=0; struct Tree { ll t1[maxn<<1],t2[maxn]; int lowbit(int x) { return (x&(-x)); } void add(int x) { int k=x; for(;x<=maxn-10;x+=lowbit(x)) { t1[x]++; t2[x]+=k; } } void remove(int x) { int k=x; for(;x<=maxn-10;x+=lowbit(x)) { t1[x]--; t2[x]-=k; } } ll query(int x,int k) { ll ans=0; for(;x;x-=lowbit(x)) { ans+= (k==1) ? t1[x] : t2[x]; } return ans; } }tt; int main() { // freopen("work.in","r",stdin); // freopen("work.out","w",stdout); n=read(); m=read(); inc(i,1,n) L[i]=read(),T[i]=read(),ans+=L[i],tmp[i]=T[i]; sort(tmp+1,tmp+1+n); inc(i,1,n) tt.add(tmp[i]),ans-=tt.query(tmp[i],2); printf("%lld\n",ans); inc(i,1,m) { int pos=read(),l=read(),t=read(); ans+=(l-L[pos]),L[pos]=l; ans+=(ll)(n-tt.query(T[pos],1)+1)*T[pos]; ans+=(ll)(tt.query(T[pos],2))-T[pos]; tt.remove(T[pos]); T[pos]=t; tt.add(T[pos]); ans-=(ll)(n-tt.query(T[pos],1)+1)*T[pos]; ans-=(ll)(tt.query(T[pos],2))-T[pos]; printf("%lld\n",ans); } }
t1存的是Tpos前面的系数
t2存的是k*tpos
这样在减去t2的过程中就可以相当于所有其他位的数统一移动了
t2,t3没改完。。。 也暂时没有题解
原文地址:https://www.cnblogs.com/ZzTzZ/p/11643651.html
时间: 2024-10-06 23:37:49