zoukankan      html  css  js  c++  java
  • 【loj2639】[Tjoi2017]不勤劳的图书管理员

    #2639. 「TJOI2017」不勤劳的图书管理员

    题目描述

    加里敦大学有个帝国图书馆,小豆是图书馆阅览室的一个书籍管理员。
    他的任务是把书排成有序的,所以无序的书让他产生厌烦,两本乱序的书会让小豆产生这两本书页数的和的厌烦度。
    现在有 nnn 本被打乱顺序的书,在接下来 mmm 天中每天都会因为读者的阅览导致书籍顺序改变位置。因为小豆被要求在接下来的 mmm 天中至少要整理一次图书。
    小豆想知道,如果他前 iii 天不去整理,第 iii 天他的厌烦度是多少,这样他好选择厌烦度最小的那天去整理。

    输入格式

    第一行有两个数 n,mn, mn,m,表示有 nnn 本书和 mmm 天。
    接下来 nnn 行,每行两个数,aia_iai  viv_ivi,表示第 iii 本书本来应该放在 aia_iai 的位置,这本书有 viv_ivi 页,保证不会有放置同一个位置的书。
    接下来 mmm 行,每行两个数,xjx_jxj  yjy_jyj,表示在第 jjj 天的第 xjx_jxj 本书会和第 yjy_jyj 本书会因为读者阅读交换位置。
    保证 1≤ai,xj,yj≤n1 leq a_i, x_j, y_j leq n1ai,xj,yjn

    输出格式

    一共 mmm 行,每行一个数,第 iii 行表示前 iii 天不去整理,第 iii 天小豆的厌烦度。因为这个数可能很大,所以将结果模 109+710 ^ 9 + 7109+7 后输出。

    样例

    样例输入

    5 5
    1 1
    2 2
    3 3
    4 4
    5 5
    1 5
    1 5
    2 4
    5 3
    1 3

    样例输出

    42
    0
    18
    28
    48

    数据范围与提示

    对于 20%20\%20% 的数据,保证 1≤n,m≤50001 leq n, m leq 50001n,m5000
    对于 100%100\%100% 的数据,保证 1≤n,m≤50000,0≤vi≤1051 leq n, m leq 50000, 0 leq v_i leq 10^51n,m50000,0vi105

    题意:每本书有次序和放的位置与权值,两本位置错乱的数会对答案贡献vi+vj , 每次交换两本书的位置,问每次操作之后的权值和;

    题解:

              将位置也看成次序的权值的话,其实就是维护动态的逆序对,只不过是两对的v都要贡献答案,维护的时候记录v的和 和 个数,交换l,r对[1,l-1]和[r+1,n]没有影响,对于l和r直接判断,l的变化值为减去[l+1,r-1]里面比v[l]小的再加上比v[l]大的,r同理,树状数组套主席树

             直接分块+树状数组的话会好写很多:https://www.cnblogs.com/CQzhangyu/p/7128300.html

     

     1 #include<cstdio>
     2 #include<iostream>
     3 #include<algorithm>
     4 #include<cstring>
     5 #include<queue>
     6 #include<cmath>
     7 #include<vector>
     8 #include<stack>
     9 #include<map>
    10 #define Run(i,l,r) for(int i=l;i<=r;i++)
    11 #define Don(i,l,r) for(int i=l;i>=r;i--)
    12 #define ll long long
    13 #define inf 0x3f3f3f3f
    14 using namespace std;
    15 const int N=50010,mod=1e9+7;
    16 int n,m,p[N],w[N],ls[N*1000],rs[N*1000],rt[N],Rt[N],p1[N],p2[N],sz,cnt[N*1000],sum[N*1000];
    17 char gc(){
    18     static char*P1,*P2,s[1000000];
    19     if(P1==P2)P2=(P1=s)+fread(s,1,1000000,stdin);
    20     return(P1==P2)?EOF:*P1++;
    21 }//
    22 int rd(){
    23     int x=0,f=1;char c=gc();
    24     while(c<'0'||c>'9'){if(c=='-')f=-1;c=gc();}
    25     while(c>='0'&&c<='9'){x=x*10+c-'0',c=gc();}
    26     return x*f;
    27 }//
    28 void ins(int&k,int last,int l,int r,int x,int v,int f){
    29     sum[k=++sz]=(sum[last]+v)%mod;
    30     cnt[k]=cnt[last]+f;
    31     ls[k]=ls[last],rs[k]=rs[last];
    32     if(l==r)return;
    33     int mid=(l+r)>>1;
    34     if(x<=mid)ins(ls[k],ls[last],l,mid,x,v,f);
    35     else ins(rs[k],rs[last],mid+1,r,x,v,f);
    36 }///
    37 int query(int k,int l,int r,int x,int y,int z){
    38     if(x>y)return 0;
    39     if(l==x&&r==y)return (sum[k]+1ll*w[z]*cnt[k]%mod)%mod;
    40     else{
    41         int mid=(l+r)>>1;
    42         if(y<=mid)return query(ls[k],l,mid,x,y,z);
    43         else if(x>mid)return query(rs[k],mid+1,r,x,y,z);
    44         else return (query(ls[k],l,mid,x,mid,z) +  query(rs[k],mid+1,r,mid+1,y,z))%mod;
    45     }
    46 }///
    47 int read(int x,int l,int r,int z){
    48     int ret = 0;
    49     for(int i=x;i;i-=i&-i){
    50         ret = (ret + query(Rt[i],1,n,l,r,z)) %mod;
    51     }
    52     return ret;
    53 }///
    54 void add(int x,int y,int v,int f){
    55     for(int i=x;i<=n;i+=i&-i){
    56         ins(Rt[i],Rt[i],1,n,y,v,f);
    57     }
    58 }///
    59 int Query(int k,int last,int l,int r,int x,int y,int z){
    60     if(x>y)return 0;
    61     if(l==x&&r==y)return (sum[k]-sum[last]+1ll*w[z]*(cnt[k]-cnt[last])%mod)%mod;
    62     else{
    63         int mid=(l+r)>>1;
    64         if(y<=mid)return Query(ls[k],ls[last],l,mid,x,y,z);
    65         else if(x>mid)return Query(rs[k],rs[last],mid+1,r,x,y,z);
    66         else return (Query(ls[k],ls[last],l,mid,x,mid,z) + Query(rs[k],rs[last],mid+1,r,mid+1,y,z))%mod;
    67     }
    68 }///
    69 int main(){
    70 //  freopen("loj1248.in","r",stdin);
    71 //  freopen("loj1248.out","w",stdout);
    72     n=rd(),m=rd();
    73     Run(i,1,n)p[i]=rd(),w[i]=rd();
    74     ll ans = 0;
    75     for(int i=1;i<=n;i++){
    76         ans=(ans+query(rt[i-1],1,n,p[i]+1,n,i))%mod;
    77         ins(rt[i],rt[i-1],1,n,p[i],w[i],1);
    78     }
    79     for(int i=1,x,y;i<=m;i++){
    80         x=rd();y=rd();
    81         if(x>y)swap(x,y);
    82         if(x==y){printf("%lld
    ",ans);continue;}
    83         if(p[x]>p[y])ans=(ans-w[x]-w[y])%mod;else ans=(ans+w[x]+w[y])%mod;
    84         ans -= (ll)Query(rt[y-1],rt[x],1,n,1,p[x]-1,x) + read(y-1,1,p[x]-1,x) - read(x,1,p[x]-1,x);ans%=mod;
    85         ans += (ll)Query(rt[y-1],rt[x],1,n,p[x]+1,n,x) + read(y-1,p[x]+1,n,x) - read(x,p[x]+1,n,x);ans%=mod;
    86         ans -= (ll)Query(rt[y-1],rt[x],1,n,p[y]+1,n,y) + read(y-1,p[y]+1,n,y) - read(x,p[y]+1,n,y);ans%=mod;
    87         ans += (ll)Query(rt[y-1],rt[x],1,n,1,p[y]-1,y) + read(y-1,1,p[y]-1,y) - read(x,1,p[y]-1,y);ans%=mod;
    88         ans = (ans%mod+mod)%mod;
    89         printf("%lld
    ",ans);
    90         add(x,p[x],-w[x],-1);add(y,p[y],-w[y],-1);
    91         swap(p[x],p[y]);swap(w[x],w[y]);
    92         add(x,p[x],w[x],1);add(y,p[y],w[y],1);
    93     }//
    94     return 0;
    95 }//by tkys_Austin;
    View Code

     

     

     

             

     

  • 相关阅读:
    python基础十一之装饰器进阶
    python基础十之装饰器
    python基础九之函数
    python基础八之文件操作
    python基础七之copy
    python基础七之集合
    python基础数据类型汇总
    python基础六之编码
    synchronized关键字的内存语义
    对于this和当前线程的一些理解
  • 原文地址:https://www.cnblogs.com/Paul-Guderian/p/9795815.html
Copyright © 2011-2022 走看看