zoukankan      html  css  js  c++  java
  • LOJ-2362 蚯蚓 队列优化

    LOJ-2362 蚯蚓 队列优化

    题意

    给出(n)个蚯蚓,常数(q),$ 0 < p < 1(,现进行)m(此操作,每次操作取当前最长的蚯蚓,对于最长的蚯蚓将其分为两部分,长度分别为)lfloorfrac{x}{p} floor,x - lfloorfrac{x}{p} floor$ ,且其他蚯蚓的长度都加上(q),现询问每次操作选出的最长的蚯蚓(操作前),以及最终的每个蚯蚓的长度

    [q = frac{u}{v} ]

    [1 leq n leq 10^5\ 0 leq m leq 7 imes 10^6\ 0 < u,v < 10^9\ 0 leq qle 200\ 1leq tleq71\ 0leq a_i leq 10^8 ]

    分析

    此题很容易想到维护一个堆来做,考虑到复杂度显然不可做

    于是寻找性质来优化

    易证得 后面切割的蚯蚓的前后部分分别小于等于前面切割的蚯蚓的前后部分

    于是可以利用这个性质维护三个单调递减的队列,分别用于存储原始的蚯蚓,切割后的前半部分的蚯蚓,切割后的后半部分的蚯蚓

    每次只需要要比较三个队列的队首哪个最大即可

    对于全体加上一个值,可以利用一个全局变量(tag)进行标记,对切割后的减去(q)即可。真实长度即相对的长度加上(tag)

    于是变成了一道模拟题,模拟了好久。。唉

    代码

    #include<bits/stdc++.h>
    #define int long long
    using namespace std;
    typedef long long ll;
    
    ll rd(){
    	ll x = 0;
    	char ch = getchar();
    	while(ch < '0' || ch > '9') {
    		ch = getchar();
    	}
    	while(ch >= '0' && ch <= '9'){
    		x = x * 10 + ch - '0';
    		ch = getchar();
    	}
    	return x;
    }
    
    const int maxn = 7e6 + 1e5 + 5;
    
    int que1[maxn];
    int que2[maxn];
    int que3[maxn];
    
    ll tag;
    
    
    signed main(){
    	int n = rd();
    	int m = rd();
    	int q = rd();
    	int u = rd();
    	int v = rd();
    	int t = rd();
    	for(int i = 1;i <= n;i++)
    		que1[i] = rd();
    	sort(que1 + 1,que1 + n + 1,greater<int>{});
    	int head1 = 1,tail1 = n;
    	int head2 = 1,tail2 = 0;
    	int head3 = 1,tail3 = 0;
    	for(int i = 1;i <= m;i++){
    		int n1 = tail1 >= head1 ? que1[head1] : -1e18;
    		int n2 = tail2 >= head2 ? que2[head2] : -1e18;
    		int n3 = tail3 >= head3 ? que3[head3] : -1e18;
    		if(n1 > n2) {
    			if(n1 > n3) {
    				que2[++tail2] = (que1[head1] + tag) * u / v,que3[++tail3] = que1[head1] + tag - (que1[head1] + tag) * u / v,head1++; 
    			}
    			else {
    				int tmp = que3[head3] + tag;
    				que2[++tail2] = tmp * u / v;
    				que3[++tail3] = tmp - tmp * u / v;
    				head3++;
    			}
    		}
    		else if(n2 > n3){
    			int tmp = que2[head2] + tag;
    			que2[++tail2] = tmp * u / v;
    			que3[++tail3] = tmp - tmp * u / v;
    			head2++; 
    		}
    		else {
    			int tmp = que3[head3] + tag;
    			que2[++tail2] = tmp * u / v;
    			que3[++tail3] = tmp - tmp * u / v;
    			head3++;
    		}
    		que2[tail2] -= q;
    		que3[tail3] -= q;
    		que2[tail2] -= tag;
    		que3[tail3] -= tag; 
    		if(i % t == 0) 
    				printf("%lld ",tag + max(n1,max(n2,n3)));		
    		tag += q;
    		/*
    		for(int i = head1;i <= tail1;i++)
    			cout << que1[i] +  tag << ' ';
    		puts("");
    		for(int i = head2;i <= tail2;i++)
    			cout << que2[i] +  tag << ' ';
    		puts("");
    		for(int i = head3;i <= tail3;i++)
    			cout << que3[i] +  tag << ' ';
    		puts("");*/
    	}
    	puts("");
    	for(int i = 1;i <= m + n;i++){
    		
    		int n1 = (tail1 >= head1 ? que1[head1] : -1e18);
    		int n2 = (tail2 >= head2 ? que2[head2] : -1e18);
    		int n3 = (tail3 >= head3 ? que3[head3] : -1e18);
    		//cout << n1 << ' ' << n2 << ' ' << n3 << '
    ';
    		if(n1 > n2) {
    			if(n1 > n3) {
    				if(i % t == 0) 
    					printf("%lld ",n1 + tag);
    				head1++;
    			}
    			else {
    				if(i % t == 0)
    					printf("%lld ",n3 + tag);
    				head3++;
    			}
    		}
    		else if(n2 > n3){
    			if(i % t == 0)
    				printf("%lld ",n2 + tag);
    			head2++;
    		}
    		else {
    			if(i % t == 0)
    				printf("%lld ",n3 + tag);
    			head3++;
    		}
    	}
    }
    
  • 相关阅读:
    [c++]基类对象作为函数參数(赋值兼容规则)
    easyui datagird 总计栏
    openssl之BIO系列之25---结束语
    具体解释Hibernate中的二级缓存
    记真实自己,炫精彩人生---《爱记》app使用体验
    设置-安全-手机加密功能解说
    Linux下Redis安装
    解题报告 之 HDU5317 RGCDQ
    FireFox所支持的全部标签(持续更新ing)
    本书已出版&lt;拨云见日:基于android的内核与系统架构源代码分析 &gt;
  • 原文地址:https://www.cnblogs.com/hznumqf/p/14674632.html
Copyright © 2011-2022 走看看