• [树状数组]Logistyka


    题目描述

    维护一个长度为n的序列,一开始都是0,支持以下两种操作:
    1.U k a 将序列中第k个数修改为a。
    2.Z c s 在这个序列上,每次选出c个正数,并将它们都减去1,询问能否进行s次操作。
    每次询问独立,即每次询问不会对序列进行修改。

    输入

    第一行包含两个正整数n,m(1<=n,m<=1000000),分别表示序列长度和操作次数。
    接下来m行为m个操作,其中1<=k,c<=n,0<=a<=10^9,1<=s<=10^9。

    输出

    包含若干行,对于每个Z询问,若可行,输出TAK,否则输出NIE。

    样例输入

    3 8
    U 1 5
    U 2 7
    Z 2 6
    U 3 1
    Z 2 6
    U 2 2
    Z 2 6
    Z 2 1
    

    样例输出

    NIE
    TAK
    NIE
    TAK

    思路:对于第二个询问,如果序列中大于等于s的数有cnt个,那么当小于s的数之和sum>=(c-cnt)*s时,可行;否则不可行;
    用两个权值树状数组分别维护序列中小于s的数的个数及小于s的数之和
    AC代码:
    #include <iostream>
    #include<cstdio>
    #include<algorithm>
    typedef long long ll;
    using namespace std;
    
    ll a[1000005];
    struct Query{char kind;ll x,y;}q[1000005];
    ll num[1000005],tot=0;
    inline ll getid(ll x){
      return lower_bound(num+1,num+1+tot,x)-num;
    }
    ll tr_b[1000005],tr_c[1000005];
    
    inline void add(ll pos,ll x,ll y){
     for(ll i=pos;i<=tot;i+=i&(-i)) tr_b[i]+=x,tr_c[i]+=y;
    }
    
    
    inline ll getsum_b(ll pos){
      ll ret=0;
      for(ll i=pos;i>0;i-=i&(-i)) ret+=tr_b[i];
      return ret;
    }
    
    inline ll getsum_c(ll pos){
      ll ret=0;
      for(ll i=pos;i>0;i-=i&(-i)) ret+=tr_c[i];
      return ret;
    }
    
    int main()
    {
        ll n,m;scanf("%lld%lld",&n,&m);
        for(ll i=1;i<=m;i++){
            scanf(" %c%lld%lld",&q[i].kind,&q[i].x,&q[i].y);
            num[++tot]=q[i].y;
        }
        sort(num+1,num+1+tot);
        tot=unique(num+1,num+1+tot)-(num+1);
        for(ll i=1;i<=m;i++){
            if(q[i].kind=='U'){
                ll pos=q[i].x,x=q[i].y;
                if(a[pos]){
                    add(getid(a[pos]),-1,-a[pos]);
                }
                a[pos]=x;
                add(getid(a[pos]),1,a[pos]);
            }
            else{
                ll c=q[i].x,s=q[i].y;
                ll cnt=getsum_b(tot)-getsum_b(getid(s)-1);
                ll sum=getsum_c(getid(s)-1);
                if(sum>=(c-cnt)*s) puts("TAK");
                else puts("NIE");
            }
        }
        return 0;
    }
     
    转载请注明出处:https://www.cnblogs.com/lllxq/
  • 相关阅读:
    C# 大小写转换(非金额)
    DataService系列教程 (一)
    C# 大小写转换(金额)
    sql注入杂谈(一)union select
    sql注入杂谈(二)报错注入
    python正则提取txt文本
    sql注入杂谈(三)盲注
    对指定网站渗透的一些总结
    MSF的利用
    SQLMAP怎么拿shell
  • 原文地址:https://www.cnblogs.com/lllxq/p/10115613.html
Copyright © 2020-2023  润新知