bzoj4889 [Tjoi2017]不勤劳的图书管理员(线段树套权值线段树)

16人阅读 评论(0) 收藏 举报
分类:

相当于动态维护带权逆序对。
交换x,y位置的数,只会对他们之间的数产生影响。分类讨论即可。我写的线段树套权值线段树,卡空间,需要写垃圾回收qaq
复杂度O(nlog2n)

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
using namespace std;
#define ll long long
#define inf 0x3f3f3f3f
#define N 50010
#define mod 1000000007
inline char gc(){
    static char buf[1<<16],*S,*T;
    if(S==T){T=(S=buf)+fread(buf,1,1<<16,stdin);if(T==S) return EOF;}
    return *S++;
}
inline int read(){
    int x=0,f=1;char ch=gc();
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=gc();}
    while(ch>='0'&&ch<='9') x=x*10+ch-'0',ch=gc();
    return x*f;
}
int n,m,rt[N<<2],owo=0,cnt,sum,ans=0;
struct book{
    int id,v;
}a[N];
struct node{
    int cnt,lc,rc,sum;
}tr[N*256];
queue<int>rec;
inline void del(int &p){
    tr[p].lc=tr[p].rc=tr[p].cnt=tr[p].sum=0;rec.push(p);p=0;
}
inline int newp(){
    int p=0;
    if(!rec.empty()) p=rec.front(),rec.pop();
    else p=++owo;return p;
}
inline void add(int &p,int l,int r,int x,int op,int val){
    if(!p) p=newp();tr[p].cnt+=op;tr[p].sum+=op*val;tr[p].sum%=mod;
    if(l==r) return;int mid=l+r>>1;
    if(x<=mid) add(tr[p].lc,l,mid,x,op,val);
    else add(tr[p].rc,mid+1,r,x,op,val);if(!tr[p].cnt) del(p);
}
inline void ask(int p,int l,int r,int x,int y){
    if(!p) return;if(x<=l&&r<=y){cnt+=tr[p].cnt;(sum+=tr[p].sum)%=mod;return;}
    int mid=l+r>>1;if(x<=mid) ask(tr[p].lc,l,mid,x,y);
    if(y>mid) ask(tr[p].rc,mid+1,r,x,y);
}
inline void change(int p,int l,int r,int x,int y){
    if(x!=y) add(rt[p],1,n,a[x].id,-1,a[x].v);
    add(rt[p],1,n,a[y].id,1,a[y].v);if(l==r) return;int mid=l+r>>1;
    if(x<=mid) change(p<<1,l,mid,x,y);
    else change(p<<1|1,mid+1,r,x,y);
}
inline void Ask(int p,int l,int r,int x,int y,int L,int R){
    if(L>R) return;
    if(x<=l&&r<=y){ask(rt[p],1,n,L,R);return;}
    int mid=l+r>>1;if(x<=mid) Ask(p<<1,l,mid,x,y,L,R);
    if(y>mid) Ask(p<<1|1,mid+1,r,x,y,L,R);
}
int main(){
//  freopen("book5.in","r",stdin);
    n=read();m=read();
    for(int i=1;i<=n;++i){
        a[i].id=read(),a[i].v=read(),change(1,1,n,i,i);
        cnt=0;sum=0;ask(rt[1],1,n,a[i].id+1,n);
        (ans+=((ll)cnt*a[i].v%mod+sum)%mod)%=mod;
    }while(m--){
        int x=read(),y=read();if(x>y) swap(x,y);
        if(x==y){printf("%d\n",ans);continue;}
        int L=a[x].id,R=a[y].id,mn=min(L,R),mx=max(L,R);
        cnt=0;sum=0;Ask(1,1,n,x,y,mn+1,mx-1);
        ans+=(mn==L?1:-1)*(2*sum%mod+(ll)(cnt+1)*(a[x].v+a[y].v)%mod)%mod;
        ans%=mod;
        cnt=0;Ask(1,1,n,x,y,1,mn-1);(ans+=(ll)cnt*(a[y].v-a[x].v)%mod)%=mod;
        cnt=0;Ask(1,1,n,x,y,mx+1,n);(ans+=(ll)cnt*(a[x].v-a[y].v)%mod)%=mod;
        if(ans<0) ans+=mod;
        change(1,1,n,x,y);change(1,1,n,y,x);swap(a[x],a[y]);printf("%d\n",ans);
    }return 0;
}
查看评论

[BZOJ4889][Tjoi2017]不勤劳的图书管理员-分块-树状数组

不勤劳的图书管理员Description加里敦大学有个帝国图书馆,小豆是图书馆阅览室的一个书籍管理员。他的任务是把书排成有序的,所以无序的书让他产生厌烦,两本乱序的书会让小豆产生这两本书页数的和的厌烦...
  • zlttttt
  • zlttttt
  • 2018年01月01日 00:37
  • 126

[BZOJ4889][洛谷P3759][TJOI2017]不勤劳的图书管理员 分块+树状数组

分块+树状数组
  • baidu_36797646
  • baidu_36797646
  • 2017年10月17日 09:20
  • 196

树套树-线段树套平衡树

树套树-线段树套平衡树的总结。
  • zzkksunboy
  • zzkksunboy
  • 2017年04月15日 16:30
  • 1344

【bzoj3110】[Zjoi2013]K大数查询 权值线段树套区间线段树

权值线段树套区间线段树 外层线段树按照完全二叉树的建法全部建出 内层线段树动态开点 外层的每个节点上都建一棵区间线段树,维护权值在[l,r]中每个区间出现的个数 每次修改对应外层线段树上的O(...
  • u012288458
  • u012288458
  • 2016年04月13日 10:39
  • 431

【BZOJ3110】【Zjoi2013】K大数查询 树套树 权值线段树套区间线段树

题解: 外层权值线段树,内层区间线段树可解。 权值都是1~n,就不用离散化了。 我写了标记永久化。 其它心得神马的: 天生对树形数据结构无爱。 第一次写树套树,终于知道是怎么回事了。 (只针对...
  • Vmurder
  • Vmurder
  • 2015年01月22日 15:14
  • 2293

bzoj3110(线段树套线段树、树状数组套线段树)

http://www.lydsy.com/JudgeOnline/problem.php?id=3110 题意: 有N个位置,M个操作。操作有两种,每次操作如果是1 a b c的形式表示在第a个位...
  • zjy2015302395
  • zjy2015302395
  • 2017年05月31日 18:43
  • 395

BZOJ 3110 ZJOI 2013 K大数查询 树套树(权值线段树套区间线段树)

题目大意:有一些位置,这些位置上可以放若干个数字。现在有两种操作。 1.在区间l到r上添加一个数字x 2.求出l到r上的第k大的数字是什么 思路:这种题一看就是树套树,关键是怎么套,怎么...
  • jiangyuze831
  • jiangyuze831
  • 2014年10月09日 14:03
  • 1199

数据结构入门4—权值线段树

一开始还以为是什么高级东东。 就是一个线段树,只不过下标是代表数字的值。 来看一个经典问题(来自http://blog.csdn.net/loi__dijiang/article/details/...
  • qq_36721333
  • qq_36721333
  • 2017年08月08日 11:57
  • 624

[树套树] 可持久化线段树 树状数组套值域线段树

大家都很强, 可与之共勉。q l, r, k查询[l, r] 第k小。m pos, x; 把pos位置的改为x。#include "cstdio" #include "cctype" #includ...
  • simpsonk
  • simpsonk
  • 2017年04月04日 15:45
  • 326

bzoj 1901 有更新区间第k大 树状数组套可持久化线段树

http://www.lydsy.com/JudgeOnline/problem.php?id=1901 我的可持久化线段树消耗的内存太大了,在zoj超内存 如果对 上次的那题无修改的区间第k大的...
  • haha593572013
  • haha593572013
  • 2012年10月09日 19:54
  • 3531
    个人资料
    持之以恒
    等级:
    访问量: 9万+
    积分: 1万+
    排名: 2009
    文章分类
    文章存档
    最新评论