zoukankan      html  css  js  c++  java
  • [loj#2529] [ZJOI2018] 胖

    题意简述

    直线上有 (n) 个点,第 (i) 个点与第 (i+1) 个点之间连双向边,边权为 (w[i])
    另有一点 (S)
    (m) 次询问:给定 (k) 条连接 (S) 与直线上一点的双向边(有边权),在新图上以 (S) 为源点跑 (Bellman-Ford) ,求跑完后所有点被更新次数的总和。

    (n,m,k leq 2 imes 10^5)


    想法

    更新次数看上去难搞,仔细想后发现,对直线上每一个点,将 (S) 分别通过 (k) 条路走到该点的路径的边权和 (s) 及 路径上经过的边数 (t) 做一个单调队列(随 (t) 增大,(s) 减小),则该点被更新的次数就是单调队列中的元素数目。

    发现仍不太好做。转而考虑每条从 (S) 到直线的边可以更新多少点,发现是一个区间。
    于是二分+st表判断求区间的两端。注意计数时不要记重了……
    复杂度 (O(nlog^2n))


    总结

    思想

    可以换对象考虑问题。
    要有影响区间的意识,二分意识。

    码力

    (set) 中似乎不一定 --s.begin()==s.end() ,所以用 (upper\_ bound) 时如果想 (--) 的话最好先判断再减。
    注意操作对象……


    代码

    #include<cstdio>
    #include<iostream>
    #include<algorithm>
    #include<set>
    
    #define INF 1e18
    
    using namespace std;
    
    int read(){
    	int x=0;
    	char ch=getchar();
    	while(!isdigit(ch)) ch=getchar();
    	while(isdigit(ch)) x=x*10+ch-'0',ch=getchar();
    	return x;
    }
    
    const int N = 200005;
    typedef long long ll;
    
    int n,m,k;
    int w[N];
    ll s[N];
    
    struct data{
    	int a,l;
    	bool operator < (const data &b) const{ return a<b.a; }
    }d[N];
    
    ll st1[N][18],st2[N][18];
    set<int> Set;
    set<int>::iterator it;
    int mp[N],Log[N];
    
    ll Min1(int l,int r) { 
    	if(l>r || l<0 || r>k) return INF;
    	int len=r-l+1,j=Log[len];
    	return min(st1[l][j],st1[r-(1<<j)+1][j]);
    }
    ll Min2(int l,int r) { 
    	if(l>r || l<0 || r>k) return INF;
    	int len=r-l+1,j=Log[len];
    	return min(st2[l][j],st2[r-(1<<j)+1][j]);
    }
    
    int main()
    {
    	n=read(); m=read();
    	for(int i=1;i<n;i++) w[i]=read();
    	for(int i=1;i<n;i++) s[i]=s[i-1]+w[i];
    	
    	int t=0,cur=1;
    	for(int i=1;i<=n;i++){
    		if(i==cur) Log[i]=t++,cur*=2;
    		else Log[i]=t-1;
    	}
    	
    	while(m--){
    		k=read();
    		for(int i=1;i<=k;i++) d[i].a=read(),d[i].l=read(),Set.insert(d[i].a);
    		
    		sort(d+1,d+1+k);
    		for(int i=1;i<=k;i++) mp[d[i].a]=i;
    		for(int i=1;i<=k;i++) st1[i][0]=d[i].l+s[n-1]-s[d[i].a-1];
    		for(int i=1;i<=k;i++) st2[i][0]=d[i].l+s[d[i].a-1];
    		for(int j=1;j<18;j++){
    			int len=(1<<j);
    			for(int i=1;i+len-1<=k;i++){
    				st1[i][j]=min(st1[i][j-1],st1[i+len/2][j-1]);
    				st2[i][j]=min(st2[i][j-1],st2[i+len/2][j-1]);
    			}
    		}
    		ll ans=0;
    		for(int i=1;i<=k;i++){
    			int l=d[i].a,r=n,mid,bon,lm,rm;
    			while(l<r){
    				mid=(l+r+1)>>1;
    				it=Set.upper_bound(2*mid-d[i].a);
    				if(it!=Set.begin()) bon=mp[*(--it)]; else bon=0; 
    				it=Set.upper_bound(mid);
    				if(it!=Set.begin()) lm=mp[*(--it)]; else lm=i;
    				it=Set.lower_bound(mid);
    				if(it!=Set.end()) rm=mp[*it]; else rm=k+1;
    				
    				if(bon>0 && d[bon].a+d[i].a==mid*2 && st1[i][0]-(s[n-1]-s[mid-1])==st2[bon][0]-s[mid-1]){
    					if(Min1(i+1,lm)>st1[i][0] && Min2(rm,bon-1)-s[mid-1]>st1[i][0]-(s[n-1]-s[mid-1])) l=mid;
    					else r=mid-1;
    				}
    				else if(Min1(i+1,lm)>st1[i][0] && Min2(rm,bon)-s[mid-1]>st1[i][0]-(s[n-1]-s[mid-1])) l=mid;
    				else r=mid-1;
    			}
    			ans+=l-d[i].a+1; 
    			l=1;r=d[i].a; 
    			while(l<r){
    				mid=(l+r)>>1; 
    				it=Set.lower_bound(2*mid-d[i].a);
     				if(it!=Set.end()) bon=mp[*it]; else bon=k+1;
    				it=Set.upper_bound(mid);
    				if(it!=Set.begin()) lm=mp[*(--it)]; else lm=0;
    				it=Set.lower_bound(mid);
    				if(it!=Set.end()) rm=mp[*it]; else rm=i;
    				
    				if(bon<=k && d[bon].a+d[i].a==mid*2 && st1[bon][0]-(s[n-1]-s[mid-1])==st2[i][0]-s[mid-1]) l=mid+1;
    				else if(Min2(rm,i-1)>st2[i][0] && Min1(bon,lm)-(s[n-1]-s[mid-1])>st2[i][0]-s[mid-1]) r=mid;
    				else l=mid+1;
    			}
    			ans+=d[i].a-l;
    		}
    		printf("%lld
    ",ans);
    		
    		//clear
    		for(int i=1;i<=k;i++){
    			Set.erase(d[i].a);
    			mp[d[i].a]=0;
    		}
    	}
    	
    	return 0;
    }
    
  • 相关阅读:
    Windows OS上安装运行Apache Kafka教程
    CSS3 transition属性
    CSS3新增UI样式
    css3响应式布局
    CSS3弹性盒模型
    CSS3
    移动端开发的那点事儿
    git开源项目协作
    移动端(IOS)iframe监听不到 onscroll 事件
    Javascript高级程序设计读书笔记(第10章 DOM)
  • 原文地址:https://www.cnblogs.com/lindalee/p/13137936.html
Copyright © 2011-2022 走看看