zoukankan      html  css  js  c++  java
  • CodeForces

    博主的 ( m bibi) 时间

    “不会还有人不知道区间 ([l,r]) 的长度是 (r-l) 吧?”

    题目

    传送门

    解法

    还是来理一理思路吧。

    先考虑弱化版:询问在 ([l,r]) 中线段的并的长度。

    (1)(n) 的顺序加入线段,用 set 来维护。需要维护三个值 ((l,r,t)),其中 (l,r) 是线段端点,(t)最新 覆盖此区间的编号。需要注意的是,当 (t) 相等时必须保证线段不相交。

    有什么用呢?实际上我们预先按顺序加入线段,用 vector 存储每个时间包含的线段(还需要存储上一个时间戳)。将询问按右端点排序,假设当前询问为 ([l,r]),则计算第 (r) 个时间对应的线段。那么 (le r) 的条件一定满足,于是定义 (f(i)) 为时间戳 (ge i) 的线段并长度。思考一下线段 ([L,R]) 的时间戳从 (t) 变到 (t') 会有什么影响:对于 (iin [t+1,t'])(f(i)) 都加上了 (R-L)。这个可以差分一下。

    如果强制在线呢?将差分数组改成线段树,再可持久化一下即可。


    回到这道题,我们要求前 (k) 大区间的权值和(权值定义为线段的并的长度)。可以考虑二分第 (k) 大区间的权值,设当前二分到 ( m mid),那么问题转化为查询权值 (ge m mid) 的区间的个数与权值和。需要注意的是可能有多个权值为第 (k) 大的区间,但由于已经知道这些区间的权值与个数,减去即可。另:如果查询权值 (> m mid) 的区间的话,(k-1) 可能等于 (0),二分就会不停往大分。

    在检验函数中,你会发现大区间的权值一定比它包含的小区间的权值大。基于此就可以用 ( ext{two-pointers}) 查询权值 (ge m mid) 的区间:(r) 右移,计算第 (r) 个时间对应的线段。维护 (l) 为此情况下权值 (ge m mid) 的最大左端时间,那么 ([1,l]) 都是合法的。

    还有一些细节,代码加了注释。

    代码

    #include <bits/stdc++.h>
    using namespace std;
    
    #define rep(i,_l,_r) for(signed i=(_l),_end=(_r);i<=_end;++i)
    #define fep(i,_l,_r) for(signed i=(_l),_end=(_r);i>=_end;--i)
    #define erep(i,u) for(signed i=head[u],v=to[i];i;i=nxt[i],v=to[i])
    #define efep(i,u) for(signed i=Head[u],v=to[i];i;i=nxt[i],v=to[i])
    #define print(x,y) write(x),putchar(y) 
    #define debug(...) do {cerr<<__LINE__<<" : ("#__VA_ARGS__<<") = "; Out(__VA_ARGS__); cerr<<flush;} while(0)
    template <typename T> void Out(T x) {cerr<<x<<"
    ";}
    template <typename T,typename ...I> void Out(T x,I ...NEXT) {cerr<<x<<", "; Out(NEXT...);}
    
    template <class T> inline T read(const T sample) {
        T x=0; int f=1; char s;
        while((s=getchar())>'9'||s<'0') if(s=='-') f=-1;
        while(s>='0'&&s<='9') x=(x<<1)+(x<<3)+(s^48),s=getchar();
        return x*f;
    }
    template <class T> inline void write(const T x) {
        if(x<0) return (void) (putchar('-'),write(-x));
        if(x>9) write(x/10);
        putchar(x%10^48);
    }
    
    typedef long long ll;
    typedef pair <ll,ll> pii;
    #define int long long
    
    const int maxn=3e5+5;
    
    int n,m;
    ll add[maxn];
    struct node {
    	int l,r,t;
    	
    	bool operator < (const node fk) const {
    		return l<fk.l;
    	}
    };
    set <node> s;
    vector <pii> g[maxn];
    typedef set <node> :: iterator Type;
    
    Type split(int x) {
    	Type it=s.lower_bound((node){x,0,0});
    	if(s.end()!=it and it->l==x) return it;
    	--it;
    	if(it==s.end() or it->r==x) return s.end();
    	node tmp=*it;
    	s.erase(it);
    	s.insert((node){tmp.l,x,tmp.t});
    	return s.insert((node){x,tmp.r,tmp.t}).first;
    }
    
    pii ask(int x) {
    	pii tt,ret; int L=0;
    	ll sum=0,tmp=0;
    	rep(i,1,n) add[i]=0;
    	rep(i,1,n) {
    		for(int j=0;j<g[i].size();++j) {
    			tt=g[i][j];
    			/*
    				当 L>=tt.first 则 [tt.first,L] 一定满足条件,先加入 sum,为避免重复不加入差分数组
    			*/
    			if(tt.first>L)
    				add[tt.first]+=tt.second;
    			else {
    				tmp+=tt.second;
    				sum+=1ll*tt.second*(0ll+L-tt.first+1); 
    			}
    			add[i+1]-=tt.second;
    		}
    		while(L+1<=i and tmp+add[L+1]>=x) {
    			tmp+=add[L+1];
    			sum+=tmp; ++L;
    		}
    		ret.first+=L,ret.second+=sum;
    	}
    	return ret;
    }
    
    signed main() {
    	n=read(9),m=read(9);
    	s.insert((node){0,(int)1e9,0});
    	rep(i,1,n) {
    		int a=read(9),b=read(9);
    		Type L=split(a),R=split(b); 
    		while(L!=R) {
    			g[i].push_back(make_pair(L->t+1,L->r-L->l));
    			s.erase(L++);
    		}
    		s.insert((node){a,b,i});
    	} 
    	int l=0,r=1e9,mid; pii ret;
     	while(l<r) {
    		mid=l+r+1>>1; 
    		ret=ask(mid);
    		if(ret.first>=m) l=mid;
    		else r=mid-1;
    	}
    	ret=ask(l);
    	print(ret.second-1ll*(ret.first-m)*l,'
    ');
    	return 0;
    }
    
  • 相关阅读:
    [转] jQuery 操作 JSON 数据
    [转] 8张图学习javascript
    HTML文档类型声明的坑...
    Android 应用内HttpClient 与 WebView 共享 Cookie
    李嘉诚无锡演讲
    keytool 生成 Android SSL 使用的 BKS
    LeetCode-344-反转字符串
    LeetCode-342-4的幂
    LeetCode-338-比特位计数
    LeetCode-326-3的幂
  • 原文地址:https://www.cnblogs.com/AWhiteWall/p/15010078.html
Copyright © 2011-2022 走看看