zoukankan      html  css  js  c++  java
  • BZOJ4889: [TJOI2017]不勤劳的图书管理员

    BZOJ4889: [TJOI2017]不勤劳的图书管理员

    额,这个题由于被卡评测了,于是变成了权限题。。。

    本蒟蒻表示没钱氪金。。。

    当然,可以去洛谷/$LOJ$搞搞事。。。

    洛谷P3759 [TJOI2017]不勤劳的图书管理员

    LOJ#2639. 「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


    题解Here!

    首先,题目可以转化为:

    1. 区间询问关键字$<x$的元素个数,和这些元素的$val$之和。
    2. 单点修改。

    对某一本书统计厌烦度时只需这么统计:$$ans+= ext{给它作出贡献的书的总页数}+ ext{给它作出贡献的书的个数} imes ext{自己的页数}$$

    然后这个显然树套树维护。

    我用了树状数组套动态开点权值线段树。

    网上还有分块套树状数组的题解,太神了。。。

    本蒟蒻好菜啊。。。

    附代码:

    #include<iostream>
    #include<algorithm>
    #include<cstdio>
    #define MAXN 50010
    #define MOD 1000000007LL
    using namespace std;
    int n,m;
    long long ans=0;
    int root[MAXN];
    struct Book{
    	int x,val;
    }book[MAXN];
    inline int read(){
    	int date=0,w=1;char c=0;
    	while(c<'0'||c>'9'){if(c=='-')w=-1;c=getchar();}
    	while(c>='0'&&c<='9'){date=date*10+c-'0';c=getchar();}
    	return date*w;
    }
    inline int lowbit(int x){return x&(-x);}
    namespace BIT{
    	long long s[MAXN],sum[MAXN];
    	inline void add(int x,long long v){for(;x<=n;x+=lowbit(x)){s[x]++;sum[x]+=v;}}
    	inline long long get_num(int x){long long ans=0;for(;x;x-=lowbit(x))ans+=s[x];return ans;}
    	inline long long get_sum(int x){long long ans=0;for(;x;x-=lowbit(x))ans+=sum[x];return ans;}
    }
    namespace ST{
    	#define LSON(rt) a[rt].lson
    	#define RSON(rt) a[rt].rson
    	#define SUM(rt) a[rt].sum
    	#define DATA(rt) a[rt].data
    	int size=0;
    	struct Segment_Tree{
    		long long sum;
    		int data,lson,rson;
    	}a[MAXN<<8];
    	void update(int k,int v,int c,int lside,int rside,int &rt){
    		if(!rt)rt=++size;
    		DATA(rt)+=c;SUM(rt)+=v;
    		if(lside==rside)return;
    		int mid=lside+rside>>1;
    		if(k<=mid)update(k,v,c,lside,mid,LSON(rt));
    		else update(k,v,c,mid+1,rside,RSON(rt));
    	}
    	long long query_num(int l,int r,int lside,int rside,int rt){
    		if(!rt)return 0;
    		long long ans=0;
    		if(l<=lside&&rside<=r)return DATA(rt);
    		int mid=lside+rside>>1;
    		if(l<=mid)ans+=query_num(l,r,lside,mid,LSON(rt));
    		if(mid<r)ans+=query_num(l,r,mid+1,rside,RSON(rt));
    		return ans;
    	}
    	long long query_sum(int l,int r,int lside,int rside,int rt){
    		if(!rt)return 0;
    		long long ans=0;
    		if(l<=lside&&rside<=r)return SUM(rt);
    		int mid=lside+rside>>1;
    		if(l<=mid)ans+=query_sum(l,r,lside,mid,LSON(rt));
    		if(mid<r)ans+=query_sum(l,r,mid+1,rside,RSON(rt));
    		return ans;
    	}
    }
    inline void update(int x,int k,int v,int c){for(;x<=n;x+=lowbit(x))ST::update(k,v,c,1,n,root[x]);}
    inline long long query_num(int x,int y,int l,int r){
    	if(x>y||l>r)return 0;
    	long long ans=0;
    	for(;y;y-=lowbit(y))ans+=ST::query_num(l,r,1,n,root[y]);
    	for(--x;x;x-=lowbit(x))ans-=ST::query_num(l,r,1,n,root[x]);
    	return ans;
    }
    inline long long query_sum(int x,int y,int l,int r){
    	if(x>y||l>r)return 0;
    	long long ans=0;
    	for(;y;y-=lowbit(y))ans+=ST::query_sum(l,r,1,n,root[y]);
    	for(--x;x;x-=lowbit(x))ans-=ST::query_sum(l,r,1,n,root[x]);
    	return ans;
    }
    void work(){
    	int x,y;
    	while(m--){
    		x=read();y=read();
    		if(x==y){
    			printf("%lld
    ",ans);
    			continue;
    		}
    		if(x>y)swap(x,y);
    		
    		//--------------------------------------------------------------------------------
    		
    		ans=(ans+query_sum(x+1,y-1,1,book[y].x-1)%MOD+query_num(x+1,y-1,1,book[y].x-1)*book[y].val%MOD)%MOD;
    		ans=((ans-query_sum(x+1,y-1,book[y].x+1,n)%MOD+MOD)%MOD-query_num(x+1,y-1,book[y].x+1,n)*book[y].val%MOD+MOD)%MOD;
    		
    		//--------------------------------------------------------------------------------
    		
    		ans=(ans+query_sum(x+1,y-1,book[x].x+1,n)%MOD+query_num(x+1,y-1,book[x].x+1,n)*book[x].val%MOD)%MOD;
    		ans=((ans-query_sum(x+1,y-1,1,book[x].x-1)%MOD+MOD)%MOD-query_num(x+1,y-1,1,book[x].x-1)*book[x].val%MOD+MOD)%MOD;
    		
    		//--------------------------------------------------------------------------------
    		
    		if(book[x].x>book[y].x)ans=(ans-book[x].val-book[y].val+MOD)%MOD;
    		else ans=(ans+book[x].val+book[y].val)%MOD;
    		
    		//--------------------------------------------------------------------------------
    		
    		update(x,book[x].x,-book[x].val,-1);update(y,book[y].x,-book[y].val,-1);
    		swap(book[x].x,book[y].x);swap(book[x].val,book[y].val);
    		update(x,book[x].x,book[x].val,1);update(y,book[y].x,book[y].val,1);
    		
    		//--------------------------------------------------------------------------------
    		
    		printf("%lld
    ",ans);
    	}
    }
    void init(){
    	n=read();m=read();
    	for(int i=1;i<=n;i++){
    		book[i].x=read();book[i].val=read();
    		update(i,book[i].x,book[i].val,1);
    	}
    	for(int i=n;i>=1;i--){
    		BIT::add(book[i].x,book[i].val);
    		ans=(ans+BIT::get_sum(book[i].x-1)%MOD+BIT::get_num(book[i].x-1)*book[i].val%MOD)%MOD;
    	}
    }
    int main(){
    	init();
    	work();
        return 0;
    }
    
  • 相关阅读:
    55种网页常用小技巧(javascript) (转)
    如何利用RadioButtonList实现datagrid列的单选 (转)
    实现数据分类汇总的SQL语句 (转)
    在ASP.Net中两种利用CSS实现多界面的方法. (转)
    ASP.NET 中 Session 实现原理浅析 [1] 会话的建立流程
    用户控件中使用客户端脚本的控件名称问题 (转)
    快速理解.NET Framework[翻译] (转)挺不错的翻译
    table的宽度,单元格内换行问题 (转)
    实现类似Windows资源管理器的DataGrid(转)
    vs.net web项目使用visual source safe进行源代码管理(转)
  • 原文地址:https://www.cnblogs.com/Yangrui-Blog/p/9643229.html
Copyright © 2011-2022 走看看