【题解】2019/10/9 日测试

今天又是自己被虐的一天

今天难度大概是省选难度-,noip+

x姓巨佬100+0+20

g姓巨佬100+10+0

窝:60+10+0

又被爆踩了。。。

先放题面吧

【题解】2019/10/9 日测试_第1张图片

t1的话就是一个权值树状数组,先进行问题转化,将T从小到大排序,问题就成了sum(l)-n*t1-(n-1)*t2...1*tn

然后可以用线段树,权值树状数组,splay等维护

code:

#include
#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的过程中就可以相当于所有其他位的数统一移动了

 

 

【题解】2019/10/9 日测试_第2张图片

 

【题解】2019/10/9 日测试_第3张图片

 

t2,t3没改完。。。 也暂时没有题解

你可能感兴趣的:(【题解】2019/10/9 日测试)