网站access数据怎么做,扁平化网站源码,嘉兴网站建设公司,燕郊医疗网站建设题目链接
技能升级
个人思路
需要给n个技能添加技能点#xff0c;无论技能点加成如何衰减#xff0c;每次始终都是选择当前技能加点加成最高的那一项技能#xff0c;所以最后一次的加点一定也是加在当时技能攻击加成最高的那个。此时#xff0c;我们去寻找最后一次的加点…题目链接
技能升级
个人思路
需要给n个技能添加技能点无论技能点加成如何衰减每次始终都是选择当前技能加点加成最高的那一项技能所以最后一次的加点一定也是加在当时技能攻击加成最高的那个。此时我们去寻找最后一次的加点的攻击力加成的值。 详细思路过程请看Java代码的注释…
参考代码(Java/Cpp)
Java
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.StreamTokenizer;public class Main {static int n;static long m;static long[][] arr;// 快速读入对象,此处不用快读,最后几个数据点过不了,拿不足分数static StreamTokenizer st new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));public static int nextInt() throws IOException {st.nextToken();return (int) st.nval;}public static long nextLong() throws IOException {st.nextToken();return (long) st.nval;}public static void main(String[] args) throws IOException {// 技能数量n nextInt();// 加点次数,根据数据范围得为 longm nextLong();// arr[i][0] 为第 i 个 技能初次加点的攻击力加成// arr[i][1] 为第 i 个 技能加点的衰减数arr new long[n][2];for(int i 0; i n; i) {arr[i][0] nextLong();arr[i][1] nextLong();}// 查找最后一次加点时,所增加的攻击力,采用 左闭右闭区间int left 0, right 1000000; // a_i的范围while(left right) {int mid (left right) / 2;// 如果当前情况可加点次数 ≥ 限制次数 m,则 增大最后一次加点数if (check(mid)) {left mid 1;} else {right mid - 1;}}// cnt 计算当前已经加点的次数, sum 计算当前攻击力long cnt 0, sum 0;for(int i 0; i n; i) {if(arr[i][0] right) continue;long k (arr[i][0] - right) / arr[i][1] 1; // 通过等差数列的形式,计算这个技能衰减能够加点的次数cnt k;sum (arr[i][0] (arr[i][0] - (k - 1) * arr[i][1])) * k / 2; // 等差数列求和}sum (m - cnt) * right; // 可能会出现最后一次加点的值在多个技能里同时出现,并且该数量超过可以加点的限制次数 m,通过该方法减去多加的技能点System.out.println(sum);}static boolean check(long x) {long num 0;for(int i 0; i n; i) {if (arr[i][0] x) continue;num (arr[i][0] - x) / arr[i][1] 1; // 等差数列,求ai变成x需要经过几次,并记上当前ai}return num m;}
}Cpp
#include bits/stdc.h
using namespace std;
typedef long long ll;
const int N 1e5 3;int n;
ll m, a[N], b[N];int check(int x)
{ll cal 0;for(int i 0; i n; i){if(a[i] x) continue;cal (a[i] - x) / b[i] 1;}return cal m;
}int main()
{ios::sync_with_stdio(0);cin.tie(0);cin n m;for (int i 0; i n; i)cin a[i] b[i];int left 0, right 1e6;while(left right){int mid (left right) / 2;if(check(mid))left mid 1;elseright mid - 1;}ll cnt 0, res 0;for(int i 0; i n; i){if(a[i] right) continue;int k (a[i] - right) / b[i] 1;cnt k;res (a[i] * 2 - (k - 1) * b[i]) * k / 2;}res (m - cnt) * right;cout res;
}