• CF609F Frogs and mosquitoes


    题意

    (n) 只位置互不相同青蛙,第 (i) 只青蛙位置为 (x_i),舌头长度为 (t_i),能吃到 ([x_i,x_i+t_i]) 范围内的蚊子。

    (m) 只蚊子依次出现,位置为 (p_j) (可能重复),价值为 (b_j),它会被能吃掉它的最左边的青蛙吃掉,吃完它后那只青蛙的舌头长度会增长 (b_j)

    只有已经出现的蚊子都被吃了或者无法被吃掉时,新的蚊子会出现。

    问每只青蛙吃掉了多少只蚊子及最终的舌头长度。

    (1 le n,m le 10^5)(0 le x_i,t_i,p_i,b_i le 10^9)

    传送门

    思路

    将青蛙按位置排序,建一棵 (x_i+t_i) 的线段树,对于一直蚊子,在线段树上二分找到最左边的大于他位置的青蛙,判断一下青蛙的初始位置有没有超过蚊子。

    如果没有能吃掉它的青蛙,就存储起来。

    当一只青蛙舌头变长的时候,更新线段树,并回头查查有没有原先的蚊子能被吃掉,所以存储的用 (multiset) 每次去二分就可以了。

    #include <bits/stdc++.h>
    using std::pair;
    using std::make_pair;
    using std::multiset;
    #define mp make_pair 
    #define fi first
    #define se second
    const int N=200005;
    typedef long long ll;
    typedef pair<ll,int> pli;
    typedef multiset<pli>::iterator it;
    multiset<pli> s;
    ll t[N<<2];
    int n,m,ans[N],x,siz;
    struct frog{
    	int pos,id;
    	ll l;
    }a[N];
    bool cmp(frog x,frog y){
    	return x.pos<y.pos;
    }
    void push_up(int x){
    	t[x]=std::max(t[x<<1],t[x<<1|1]);
    }
    void build(int k,int l,int r){
    	if (l==r){
    		t[k]=a[l].pos+a[l].l;
    		return;
    	}
    	int mid=(l+r)>>1;
    	build(k<<1,l,mid);
    	build(k<<1|1,mid+1,r);
    	push_up(k);
    }
    int query(int k,int l,int r,int x){
    	if (t[k]<x) return -1;
    	if (l==r){
    		if (a[l].pos>x) return -1;
    		return l;
    	}
    	int mid=(l+r)>>1;
    	if (t[k<<1]>=x) return query(k<<1,l,mid,x);
    	return query(k<<1|1,mid+1,r,x);
    }
    void modify(int k,int l,int r,int x,int y){
    	if (l==r){
    		t[k]+=y;
    		return;
    	}
    	int mid=(l+r)>>1;
    	if (x<=mid) modify(k<<1,l,mid,x,y);
    	else modify(k<<1|1,mid+1,r,x,y);
    	push_up(k);
    }
    bool cmp2(frog x,frog y){
    	return x.id<y.id;
    }
    int main(){
    	scanf("%d%d",&n,&m);
    	for (int i=1;i<=n;i++)
    		scanf("%d%lld",&a[i].pos,&a[i].l),a[i].id=i;
    	std::sort(a+1,a+n+1,cmp);
    	build(1,1,n);
    	s.insert(mp(-1,0)); 
    	s.insert(mp(10000000000000000,0));
    	for (int i=1;i<=m;i++){
    		scanf("%d%d",&x,&siz);
    		int id=query(1,1,n,x);
    		if (id==-1){
    			s.insert(mp(x,siz));
    			continue;
    		}
    		modify(1,1,n,id,siz);
    		ans[a[id].id]++;
    		a[id].l+=siz;
    		while (1){
    			it itt=s.upper_bound(mp(a[id].l+a[id].pos+1,-1));
    			itt--;
    			pli tt=*itt;
    			if (tt.fi==-1) break;
    			if (a[id].pos>tt.fi) break;
    			ans[a[id].id]++,a[id].l+=tt.se;
    			modify(1,1,n,id,tt.se);
    			s.erase(itt);
    		}
    	}
    	std::sort(a+1,a+n+1,cmp2);
    	for (int i=1;i<=n;i++) printf("%d %lld
    ",ans[i],a[i].l);
    }
    

    后记

    因为蚊子的价值可能是 (0),然后第一次二分搜了一个 ((t+x+1,0)) 就挂了

  • 相关阅读:
    Vue2.0 【第二季】第2节 Vue.extend构造器的延伸
    Vue2.0 【第二季】第1节 Vue.directive自定义指令
    Vue2.0 【第一季】第8节 v-pre & v-cloak & v-once
    Vue2.0 【第一季】第7节 v-bind指令
    c# tcp协议
    easyui笔记
    asp.net get中文传值乱码
    asp.net 调试,Web 服务器被配置为不列出此目录的内容。
    金蝶API 官方demo报错,解决方案
    hbuilder拍照上传,与asp.net服务器获取并保存
  • 原文地址:https://www.cnblogs.com/flyfeather6/p/13674778.html
Copyright © 2020-2023  润新知