• [P3759][TJOI2017]不勤劳的图书管理员(分块+树状数组)


    题目描述

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

    输入输出格式

    输入格式:

    第一行会有两个数,n,m分别表示有n本书,m天

    接下来n行,每行两个数,ai和vi,分别表示第i本书本来应该放在ai的位置,这本书有vi页,保证不会有放置同一个位置的书

    接下来m行,每行两个数,xj和yj,表示在第j天的第xj本书会和第yj本书会因为读者阅读交换位置

    输出格式:

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

    输入输出样例

    输入样例#1: 复制
    5 5
    1 1
    2 2
    3 3
    4 4
    5 5
    1 5
    1 5
    2 4
    5 3
    1 3
    输出样例#1: 复制
    42
    0
    18
    28
    48

    说明

    对于20%的数据,1 ≤ ai; xj; yj ≤ n ≤ 5000, m ≤ 5000, vi ≤ 10^5

    对于100%的数据,1 ≤ ai; xj; yj ≤ n ≤ 50000, m ≤ 50000, vi ≤ 10^5

    不想写或者不会写数据结构的用分块就好,然后有两种写法,一种是对每一块排序,一种是对每块维护一个树状数组。

    这样分L和R在同一块,L和R所在的两个不完整的块,L和R跨过的完整的块三种情况讨论即可。

    注意!!这题前两种情况一定不能暴力重建块!暴力重建的用时是1200+s,如果只更新变化的部分就只要80+s。

    还有一个问题,因为整块标记的复杂度是$O(frac{n}{S}  log n)$的(其中S是块的大小),所以S设为$sqrt{n log n}$的速度是设为$sqrt{n}$的两倍。

     1 #include<cmath>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<algorithm>
     5 typedef long long ll;
     6 #define rep(i,l,r) for (register int i=l; i<=r; i++)
     7 using namespace std;
     8 
     9 const ll N=50100,md=1000000007;
    10 int n,m,mx,L,R,B,a[N],v[N],sz[N],bl[N],cnt,sum[N],d[300],c[250][N],c1[250][N],ans;
    11 
    12 void add(int c[],int x,int k){ for (; x<=n; x+=x&-x) c[x]=(c[x]+k)%md; }
    13 int que(int c[],int x){ ll res=0; for (; x; x-=x&-x) res=(res+c[x])%md; return res; }
    14 void add1(int c1[],int x,int k){ for (; x<=n; x+=x&-x) c1[x]=(c1[x]+k)%md; }
    15 int que1(int c1[],int x){ ll res=0; for (; x; x-=x&-x) res=(res+c1[x])%md; return res; }
    16 int get(int x){ return x>=0 ? x : x+md; }
    17 
    18 void cal(int x,int y,int z){
    19     if (a[x]<a[z]) ans=(ans+v[x]+v[z])%md; else ans=(ans-v[x]-v[z]+md+md)%md;
    20     if (a[y]<a[z]) ans=(ans+md+md-v[y]-v[z])%md; else ans=(ans+v[y]+v[z])%md;
    21 }
    22 
    23 void work(int L,int R){
    24     if (L==R) return;
    25     if (bl[L]==bl[R]){
    26         rep(i,L+1,R-1) cal(L,R,i); swap(a[L],a[R]); swap(v[L],v[R]);
    27     }else{
    28         rep(i,L+1,(bl[L]-1)*B+sz[bl[L]]) cal(L,R,i);
    29         rep(i,(bl[R]-1)*B+1,R-1) cal(L,R,i);
    30         swap(a[L],a[R]); swap(v[L],v[R]);
    31         sum[bl[L]]=(sum[bl[L]]+md-v[R]+v[L])%md; sum[bl[R]]=(sum[bl[R]]+md-v[L]+v[R])%md;
    32         add(c[bl[R]],a[L],-v[L]); add(c[bl[L]],a[R],-v[R]); add1(c1[bl[R]],a[L],-1); add1(c1[bl[L]],a[R],-1);
    33         add(c[bl[L]],a[L],v[L]); add(c[bl[R]],a[R],v[R]); add1(c1[bl[L]],a[L],1); add1(c1[bl[R]],a[R],1);
    34         rep(i,bl[L]+1,bl[R]-1){
    35             ans=get((1ll*ans-(que(c[i],a[R]-1)+1ll*que1(c1[i],a[R]-1)*v[R])%md));
    36             ans=get((1ll*ans+(que(c[i],a[L]-1)+1ll*que1(c1[i],a[L]-1)*v[L]))%md);
    37             ans=get((1ll*ans-(sum[i]-que(c[i],a[L])+1ll*(sz[i]-que1(c1[i],a[L]))*v[L]))%md);
    38             ans=get((1ll*ans+(sum[i]-que(c[i],a[R])+1ll*(sz[i]-que1(c1[i],a[R]))*v[R]))%md);
    39         }
    40     }
    41     if (a[R]<a[L]) ans=(1ll*ans+v[L]+v[R])%md; else ans=get((1ll*ans-(v[L]+v[R]))%md);
    42 }
    43 
    44 int main(){
    45     freopen("book.in","r",stdin);
    46     freopen("book.out","w",stdout);
    47     scanf("%d%d",&n,&m); B=(int)sqrt(n*17);
    48     rep(i,1,n) scanf("%d%d",&a[i],&v[i]);
    49     rep(i,1,n) bl[i]=(i-1)/B+1; mx=(n-1)/B+1;
    50     rep(i,1,mx-1) sz[i]=B; sz[mx]=n-(mx-1)*B;
    51     rep(i,1,n) add(c[bl[i]],a[i],v[i]),add1(c1[bl[i]],a[i],1),sum[bl[i]]=(sum[bl[i]]+v[i])%md;
    52     rep(i,1,n){
    53         ans=get((1ll*ans+(i-1-1ll*que1(c1[0],a[i]-1))*v[i]+cnt-que(c[0],a[i]-1))%md);
    54         add(c[0],a[i],v[i]); add1(c1[0],a[i],1); cnt=(cnt+v[i])%md;
    55     }
    56     rep(i,1,m) scanf("%d%d",&L,&R),work(min(L,R),max(L,R)),printf("%d
    ",ans);
    57     return 0;
    58 }
  • 相关阅读:
    C#关于委托。。
    webBrowser自动填充、抓取网页数据
    《后台构造DataGridView,并且根据不同条件显示不同颜色》
    Google Test入门教程:从下载到运行
    Janus安装教程,ubuntu18.04系统
    Nginx安装教程,ubuntu18.04
    博客园~O(∩_∩)O
    LRJ入门经典0903切蛋糕305
    LRJ入门经典0907万圣节的小L306
    LRJ入门经典0905邮票和信封305
  • 原文地址:https://www.cnblogs.com/HocRiser/p/8459700.html
Copyright © 2020-2023  润新知