zoukankan      html  css  js  c++  java
  • [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 }
  • 相关阅读:
    《DSP using MATLAB》 示例 Example 9.12
    《DSP using MATLAB》示例 Example 9.11
    《DSP using MATLAB》示例 Example 9.10
    《DSP using MATLAB》示例Example 9.9
    《DSP using MATLAB》示例 Example 9.8
    《DSP using MATLAB》示例Example 9.7
    《DSP using MATLAB》示例 Example 9.6
    《DSP using MATLAB》示例Example 9.5
    《DSP using MATLAB》示例 Example 9.4
    (转载)【C++11新特性】 nullptr关键字
  • 原文地址:https://www.cnblogs.com/HocRiser/p/8459700.html
Copyright © 2011-2022 走看看