zoukankan      html  css  js  c++  java
  • BZOJ 4717 改装

    Description

    【题目背景】
      小Q最近喜欢上了一款游戏,名为《舰队connection》,在游戏中,小Q指挥强大的舰队南征北战,从而成为了一名dalao。在游戏中,不仅船只能力很重要,搭配合适的装备更是如虎添翼。小Q潜心研究配装三十年,终于——把装备凑齐了。
    【题意描述】
      小Q有n艘船,m件装备。为了简单起见,我们假定每艘船都只能携带一件装备,且可以携带任何一件装备。每艘船和每件装备都有自己的能力值。船携带装备时,能力值为两者相乘。另外,小q还有可能对船或装备进行改修(强化)。改修成功会让能力提升,失败则会让能力降低。由于最佳配置已经用了无数次了毫无挑战性,因此,小Q并不打算直接使用最佳配置,而是使用相对弱一些的第k佳配置。具体来说,每次选择船只时,由于关卡限制,小Q需要在编号为L到R的船只中选择一艘,并在编号为a和b之间的装备选择一架,组成出击用的船只。于是,小Q总共有(R-L+1)*(b-a+1)种选择,小Q希望知道,所有这些选择中,第k大的能力值是多少。例如:
      船只:5 3 7
      装备:4 2 1 8 16
    对于L=1,R=3,a=1,b=5,k=10的询问,将所有可能的能力值排序,分别为7*16=102,5*16=80,7*8=56,3*16=48,5*8=40,7*4=28,3*8=24,5*4=20,7*2=14,3*4=12,5*2=10,7*1=7,3*2=6,5*1=5,3*1=3,其中第10大的是12。对于L=2,R=3,a=2,b=4,k=5的询问,将所有可能的能力值排序,分别为7*8=56,3*8=24,7*2=16,7*1=7,3*2=6,3*1=3,其中第5大的是6。假定小Q改修了第二艘船使其能力值成功增加至4,并改修了第5件装备但由于失败使得它的能力值减小为9。现在,对于L=1,R=2,A=4,B=5,K=3的询问,所有可能的能力值分别为5*9=45,5*8=40,4*9=36,
    4*8=32,其中第3大的是36。现在,你要编写一个程序回答这些问题。提示:由于游戏的特殊性,装备比船多得不知道到哪里去了,另外,作为一个人类,小Q才不会在一秒钟之内问几百万个问题让你回答,他只会问几百个,而且给你好几秒钟的时间回答。

    Input

    第一行两个数n,m,空格分隔,表示小Q的船的数量和装备的数量。
    第二行n个数,空格分隔,表示小Q的船的能力值(按编号)。
    第三行m个数,空格分隔,表示小Q的装备的能力值(按编号)。
    第四行一个数q,表示小q的操作数量。
    接下来q行,每行描述一个操作,操作要么为一个改修事件,要么为一个询问。
    对于改修事件,该行4个数0,type,pos,val,type为0或1,0表示把pos号船改修成val的能力值
    1表示把pos号装备改修成val的能力值。
    对于询问操作,该行6个数1,L,R,a,b,k,空格分隔,表示一个询问。
    n<=250,m<=100000,q<=100000,其中询问操作不会超过200。
    对于100%的数据,1<=L<=R<=n,1<=a<=b<=m,1<=k<=(R-L+1)*(b-a+1)
    任何时候船能力值为不超过2000的正整数,装备能力值为不超过1000000的正整数。

    Output

    对于每个询问操作,输出一行,包含一个数,表示询问的答案。
     
      话说我看到这题时限$100s$的时候简直惊呆了……这给人一种怎么搞都可以过的感觉啊……
      这道题由于询问特别少,修改较多,所以显然可以让询问的复杂度适量大一点。于是每次询问可以先二分一个答案$x$,然后判断大于$x$的方案有多少种即可。由于船的能力值范围很小,所以我们可以每次扫一遍$[l,r]$中的所有船,并且把能力值用一个前缀和数组存下来。然后枚举选哪一个装备,用前缀和数组算一下有多少艘船符合条件,就可以了。
      由于我二分上界设的比较大,好像跑得很慢TAT……其实好像是这样复杂度不太对……$100s$时限强行跑过去~
      下面贴代码:
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<cmath>
    #define File(s) freopen(s".in","r",stdin),freopen(s".out","w",stdout)
    #define N 310
    #define M 100010
    #define INF 2147483647
    
    using namespace std;
    typedef long long llg;
    
    int n,m,q,a[N],b[M];
    int w[N<<2];
    
    int getint(){
    	int w=0;bool q=0;
    	char c=getchar();
    	while((c>'9'||c<'0')&&c!='-') c=getchar();
    	if(c=='-') c=getchar(),q=1;
    	while(c>='0'&&c<='9') w=w*10+c-'0',c=getchar();
    	return q?-w:w;
    }
    
    int pd(int x,int l,int r){
    	int ans=0; x--;
    	for(int i=l;i<=r;i++) ans+=w[2000]-w[min(x/b[i],2000)];
    	return ans;
    }
    
    int main(){
    	File("a");
    	n=getint(); m=getint();
    	for(int i=1;i<=n;i++) a[i]=getint();
    	for(int i=1;i<=m;i++) b[i]=getint();
    	q=getint();
    	while(q--){
    		int lcf=getint();
    		if(!lcf){
    			int ty=getint(),po=getint();
    			if(!ty) a[po]=getint();
    			else b[po]=getint();
    		}
    		else{
    			int L=getint(),R=getint(),ll=getint(),rr=getint(),k=getint();
    			int l=0,r=INF,mid;
    			for(int i=1;i<=2000;i++) w[i]=0;
    			for(int i=L;i<=R;i++) w[a[i]]++;
    			for(int i=1;i<=2000;i++) w[i]+=w[i-1];
    			while(l!=r){
    				mid=((llg)l+(llg)r+1LL)>>1;
    				if(pd(mid,ll,rr)<k) r=mid-1;
    				else l=mid;
    			}
    			printf("%d
    ",l);
    		}
    	}
    	return 0;
    }
  • 相关阅读:
    JQuery插件,轻量级表单模型验证(续 二)
    关于DateTimeOffset的爱恨情仇
    JQuery插件,轻量级表单模型验证(续 一)
    asp.net 远程模型验证
    JQuery插件,轻量级表单模型验证
    Ef Core增加Sql方法
    初识依赖注入
    Core下简易WebApi
    sql语句实现行转列练习
    sql语句基本查询操作
  • 原文地址:https://www.cnblogs.com/lcf-2000/p/6059720.html
Copyright © 2011-2022 走看看