• 题解 P3527 【[POI2011]MET-Meteors】


    题目链接

    Solution [POI2011]MET-Meteors

    题目大意:给定一个环,每个点有一个所属国家,多次事件,每次对一段区间上的每个点加上一个值,求每个国家最早多少次操作之后属于它的点的点权和能达到一个它的期望值

    整体二分


    分析

    区间修改单点查询可以树状数组差分一下

    不难想到暴力思路,对于每个国家,我们二分一个时间,暴力修改,然后单点查询

    这样时间复杂度是(O(nklog_mlog_k)),应该是的?(n)个国家做(n)次操作,每次二分(log_k)次,每次树状数组复杂度(log_m),暴力做修改(k)次?

    然后我们发现这玩意儿是可以用整体二分来优化的

    首先我们假定当前答案区间在([l,r])内,我们每次做([l,mid])这段区间内的修改,如果一个国家已经达到期望就把它归到左队列,否则归到右队列,并且对其期望值做修改,只有这样才能保证时间复杂度(我就是每次改([1,mid]) (T)了一片发现自己写了个假算法……)

    对于无解,我们加一个虚拟事件,把所有点点权加上无穷大

    #include <cstdio>
    #include <cctype>
    #include <vector>
    using namespace std;
    typedef long long ll;
    const int maxn = 3e5 + 100;
    inline int read(){
    	int x = 0;char c = getchar();
    	while(!isdigit(c))c = getchar();
    	while(isdigit(c))x = x * 10 + c - '0',c = getchar();
    	return x;
    }
    int mxwant;
    namespace BIT{
    	ll f[maxn];
    	int t[maxn],tim;
    	inline int lowbit(int x){return x & (-x);}
    	inline void clear(){tim++;}
    	inline void add(int pos,int val){
    		while(pos < maxn){
    			if(t[pos] < tim)t[pos] = tim,f[pos] = 0;
    			f[pos] += val;
    			pos += lowbit(pos);
    		}
    	}
    	inline ll query(int pos){
    		ll res = 0;
    		while(pos){
    			if(t[pos] < tim)t[pos] = tim,f[pos] = 0;
    			res += f[pos];
    			pos -= lowbit(pos);
    		}
    		return res;
    	}
    }
    struct Event{
    	int l,r,val;
    }event[maxn];
    vector<int> vec[maxn];
    int n,m,k,id[maxn],want[maxn],q[maxn],q1[maxn],q2[maxn],ans[maxn];
    inline void modify(int l,int r,int val){
    	if(l <= r)BIT::add(l,val),BIT::add(r + 1,-val);
    	else BIT::add(l,val),BIT::add(1,val),BIT::add(r + 1,-val);
    }
    inline void solve(int l,int r,int ql,int qr){
    	if(ql > qr)return;
    	if(l == r){
    		for(int i = ql;i <= qr;i++)ans[q[i]] = l;
    		return;
    	}
    	int mid = (l + r) >> 1,pos1 = 0,pos2 = 0,pos = ql;
    	for(int i = l;i <= mid;i++)
    		modify(event[i].l,event[i].r,event[i].val);
    	for(int i = ql;i <= qr;i++){
    		ll tmp = 0;
    		for(int x : vec[q[i]]){
    			tmp += BIT::query(x);
    			if(tmp > want[q[i]])break;
    		}
    		if(tmp >= want[q[i]])q1[++pos1] = q[i];
    		else want[q[i]] -= tmp,q2[++pos2] = q[i];
    	}
    	BIT::clear();
    	for(int i = 1;i <= pos1;i++)q[pos++] = q1[i];
    	for(int i = 1;i <= pos2;i++)q[pos++] = q2[i];
    	solve(l,mid,ql,ql + pos1 - 1),solve(mid + 1,r,ql + pos1,qr);
    }
    int main(){
    	n = read(),m = read();
    	for(int i = 1;i <= m;i++)vec[read()].push_back(i);
    	for(int i = 1;i <= n;i++)want[i] = read(),mxwant = max(mxwant,want[i]);
    	k = read();
    	for(int i = 1;i <= k;i++)
    		event[i].l = read(),event[i].r = read(),event[i].val = read();
    	event[k + 1].l = 1,event[k + 1].r = m,event[k + 1].val = 0x7fffffff;
    	for(int i = 1;i <= n;i++)q[i] = i;
    	solve(1,k + 1,1,n);
    	for(int i = 1;i <= n;i++)
    		if(ans[i] == k + 1)printf("NIE
    ");
    		else printf("%d
    ",ans[i]);
    	return 0;
    }
    
  • 相关阅读:
    SpringCloud Config 配置中心
    MySQL 8.0版本安装后,安装目录下找不到my.ini文件
    MySQL 跨库JOIN
    SpringCloud Ribbon 自定义负载均衡算法
    idea部署tomcat,日志打印显示乱码问题解决
    centos7配置回环网卡地址
    INV*物料接收子库存更新
    AP*供应商更新
    AR*Hz_Parties 客户表更新
    MyBatis-Plus自动生成代码
  • 原文地址:https://www.cnblogs.com/colazcy/p/11855560.html
Copyright © 2020-2023  润新知