zoukankan      html  css  js  c++  java
  • BZOJ 3343 魔法

      我们注意到q很小,每次询问的区间最多被之前的修改划分成O(q)个区间,我们把每个区间放到主席树上查询。

    #pragma GCC optimize("-Ofast")
    #include<bits/stdc++.h>
    #define fi first
    #define se second
    #define N 11000007//|||
    #define Q 6007
    #define Max(a,b) (a>b?a:b)
    #define Min(a,b) (a<b?a:b) 
    #define Mid (l+r>>1)
    using namespace std;
    int n,q,x,ls[N],rs[N],key[N],rt[N/10],cnt,l[Q],r[Q],w[Q],L,R,tot,C,ans;
    long long sum;
    char ch[4];
    map<int,int> mp;
    map<int,int>:: iterator it,la;
    void add(int last,int &now,int l,int r,int pos){
        now=++cnt; key[now]=key[last]+1; if (l==r) return;
        if (pos<=Mid) rs[now]=rs[last],add(ls[last],ls[now],l,Mid,pos);
        else ls[now]=ls[last],add(rs[last],rs[now],Mid+1,r,pos);
    }
    int que(int now,int l,int r,int pos){
        if (l==r) return key[now];
        if (pos<=Mid) return key[rs[now]]+que(ls[now],l,Mid,pos);
        return que(rs[now],Mid+1,r,pos);
    }
    inline void read(int &x){
        static char c;
        for (c=getchar();!isdigit(c);c=getchar());
        for (x=0;isdigit(c);c=getchar())x=x*10+c-48;
    }
    void write(int x){if (x<10) {putchar('0'+x); return;} write(x/10); putchar('0'+x%10);}
    inline void writeln(int x){ if (x<0) putchar('-'),x*=-1; write(x); putchar('
    '); }
    inline void writel(int x){ if (x<0) putchar('-'),x*=-1; write(x); putchar(' '); }
    signed main () {
    //    cerr<<(sizeof ls*3)<<endl;
        read(n); read(q);
        for (int i=1;i<=n;i++) 
          read(x),
          add(rt[i-1],rt[i],1,1000,x); 
        for (int i=1;i<=q;i++) {
            scanf("%s",ch);
            if (ch[0]=='M') {
                read(l[++tot]); read(r[tot]); read(w[tot]); 
            }
            else {
                ans=0;
                read(L); read(R); read(C);
                mp[L-1]=C; mp[R]=-C;
                for (int j=1;j<=tot;j++) {
                    if (r[j]<L||l[j]>R) continue;
                        mp[Max(L,l[j])-1]-=w[j];
                        mp[Min(R,r[j])]+=w[j];
                }
                sum=0;
                for (it=mp.begin(),la=mp.begin();it!=mp.end();it++) {
                    if (it!=mp.begin()) {
                        if (sum>1000) {la++; continue;}
                        ans+=que(rt[it->fi],1,1000,Max(sum,1));
                        ans-=que(rt[la->fi],1,1000,Max(sum,1)); la++;
                    }
                    sum+=it->se;
                } 
                mp.clear();printf("%d
    ",ans);
            }
        }
    }
  • 相关阅读:
    Android开发中常见的错误
    使用命令行的方式向GitHub中上传本地项目
    jmeter保存测试结果到文件
    转 Jmeter参数化的4种方法
    键盘各键对应的编码值(key)
    CacheHelper对缓存的控制
    Oracle存储过程
    Oricle中SQL语法
    python学习资料百度网盘分享
    一些网站学习的链接
  • 原文地址:https://www.cnblogs.com/rrsb/p/9588429.html
Copyright © 2011-2022 走看看