zoukankan      html  css  js  c++  java
  • bzoj4889: [Tjoi2017]不勤劳的图书管理员(树套树)

    传送门

    据说正解线段树套平衡树

    然而网上参考(抄)了一个树状数组套动态开点线段树的

    思路比较清楚,看代码应该就明白了

      1 //minamoto
      2 #include<iostream>
      3 #include<cstdio>
      4 #include<cstring>
      5 #define ll long long
      6 using namespace std;
      7 const int N=50005,mod=1e9+7;
      8 #define getc() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++)
      9 char buf[1<<21],*p1=buf,*p2=buf;
     10 inline int read(){
     11     #define num ch-'0'
     12     char ch;bool flag=0;int res;
     13     while(!isdigit(ch=getc()))
     14     (ch=='-')&&(flag=true);
     15     for(res=num;isdigit(ch=getc());res=res*10+num);
     16     (flag)&&(res=-res);
     17     #undef num
     18     return res;
     19 }
     20 char sr[1<<21],z[20];int C=-1,Z;
     21 inline void Ot(){fwrite(sr,1,C+1,stdout),C=-1;}
     22 inline void print(ll x){
     23     if(C>1<<20)Ot();if(x<0)sr[++C]=45,x=-x;
     24     while(z[++Z]=x%10+48,x/=10);
     25     while(sr[++C]=z[Z],--Z);sr[++C]='
    ';
     26 }
     27 int n,m,a[N],b[N],c[N],cntt[N];
     28 ll ans;
     29 inline void add(int x,int y){
     30     for(;x<=n;x+=x&-x) c[x]+=y,++cntt[x];
     31 }
     32 inline ll sum_v(int x){
     33     ll res=0;
     34     for(;x;x-=x&-x) res+=c[x];return res;
     35 }
     36 inline ll sum_cnt(int x){
     37     ll res=0;
     38     for(;x;x-=x&-x) res+=cntt[x];return res;
     39 }
     40 int tot,rt[N],cnt[N<<8],L[N<<8],R[N<<8];ll v[N<<8];
     41 void insert(int &p,int l,int r,int x,int k,int t){
     42     if(!p) p=++tot;v[p]+=k,cnt[p]+=t;
     43     if(l==r) return;int mid=l+r>>1;
     44     if(x<=mid) insert(L[p],l,mid,x,k,t);
     45     else insert(R[p],mid+1,r,x,k,t);
     46 }
     47 inline void add(int x,int y,int k,int t){
     48     for(;x<=n;x+=x&-x) insert(rt[x],1,n,y,k,t);
     49 }
     50 int query_v(int p,int l,int r,int ql,int qr){
     51     if(!p) return 0;
     52     if(ql<=l&&qr>=r) return v[p];int mid=l+r>>1;
     53     int res=0;
     54     if(ql<=mid) res+=query_v(L[p],l,mid,ql,qr);
     55     if(qr>mid) res+=query_v(R[p],mid+1,r,ql,qr);
     56     return res;
     57 }
     58 int query_cnt(int p,int l,int r,int ql,int qr){
     59     if(!p) return 0;
     60     if(ql<=l&&qr>=r) return cnt[p];int mid=l+r>>1;
     61     int res=0;
     62     if(ql<=mid) res+=query_cnt(L[p],l,mid,ql,qr);
     63     if(qr>mid) res+=query_cnt(R[p],mid+1,r,ql,qr);
     64     return res;
     65 }
     66 ll Q_v(int l,int r,int ql,int qr){
     67     if(l>r||ql>qr) return 0;
     68     ll res=0;
     69     for(;r;r-=r&-r) res+=query_v(rt[r],1,n,ql,qr);
     70     for(--l;l;l-=l&-l) res-=query_v(rt[l],1,n,ql,qr);return res;
     71 }
     72 ll Q_cnt(int l,int r,int ql,int qr){
     73     if(l>r||ql>qr) return 0;
     74     ll res=0;
     75     for(;r;r-=r&-r) res+=query_cnt(rt[r],1,n,ql,qr);
     76     for(--l;l;l-=l&-l) res-=query_cnt(rt[l],1,n,ql,qr);return res;
     77 }
     78 inline void dec(ll &x,ll y){
     79     while(x<y) x+=mod;x-=y;
     80 }
     81 int main(){
     82     //freopen("testdata.in","r",stdin);
     83     n=read(),m=read();
     84     for(int i=1;i<=n;++i) a[i]=read(),b[i]=read();
     85     for(int i=n;i;--i) add(a[i],b[i]),(ans+=sum_v(a[i]-1)+sum_cnt(a[i]-1)*b[i])%=mod;
     86     for(int i=1;i<=n;++i) add(i,a[i],b[i],1);
     87     while(m--){
     88         int l=read(),r=read();
     89         if(l>r) swap(l,r);
     90         if(l==r) {print(ans);continue;}
     91         (ans+=Q_v(l+1,r-1,1,a[r]-1))%=mod;
     92         (ans+=Q_cnt(l+1,r-1,1,a[r]-1)*b[r])%=mod;
     93         dec(ans,Q_v(l+1,r-1,a[r]+1,n));
     94         dec(ans,Q_cnt(l+1,r-1,a[r]+1,n)*b[r]);
     95         (ans+=Q_v(l+1,r-1,a[l]+1,n))%=mod;
     96         (ans+=Q_cnt(l+1,r-1,a[l]+1,n)*b[l])%=mod;
     97         dec(ans,Q_v(l+1,r-1,1,a[l]-1));
     98         dec(ans,Q_cnt(l+1,r-1,1,a[l]-1)*b[l]);
     99         if(a[l]>a[r]) dec(ans,b[l]+b[r]);
    100         else (ans+=b[l]+b[r])%=mod;
    101         add(l,a[l],-b[l],-1),add(l,a[r],b[r],1);
    102         add(r,a[r],-b[r],-1),add(r,a[l],b[l],1);
    103         swap(a[l],a[r]),swap(b[l],b[r]);
    104         print(ans);
    105     }
    106     Ot();
    107     return 0;
    108 }
  • 相关阅读:
    构建之法第九、十章读后感
    构建之法第七章读后感
    构建之法五、六章读后感
    构建之法第四章读后感
    一组阶段小记之再读构建之法
    打印控件
    TTS语音
    VS2005通过网络连接CE设备进行调试开发
    Windows XP下安装WinCE6.0开发环境
    利用VS2005创建WINCE 6.0 平台
  • 原文地址:https://www.cnblogs.com/bztMinamoto/p/9570180.html
Copyright © 2011-2022 走看看