目录

  • E. Accidental Victory
    • D. Permutation Transformation
      • G. Old Floppy Drive

E. Accidental Victory

main idea:二分查找,贪心;

A championship is held in Berland, in which n players participate. The player with the number i has ai (ai≥1) tokens.
The championship consists of n−1 games, which are played according to the following rules:
in each game, two random players with non-zero tokens are selected;
the player with more tokens is considered the winner of the game (in case of a tie, the winner is chosen randomly);
the winning player takes all of the loser’s tokens;
The last player with non-zero tokens is the winner of the championship.
All random decisions that are made during the championship are made equally probable and independently.
For example, if n=4, a=[1,2,4,3], then one of the options for the game (there could be other options) is:
during the first game, the first and fourth players were selected. The fourth player has more tokens, so he takes the first player’s tokens. Now a=[0,2,4,4];
during the second game, the fourth and third players were selected. They have the same number of tokens, but in a random way, the third player is the winner. Now a=[0,2,8,0];
during the third game, the second and third players were selected. The third player has more tokens, so he takes the second player’s tokens. Now a=[0,0,10,0];
the third player is declared the winner of the championship.
Championship winners will receive personalized prizes. Therefore, the judges want to know in advance which players have a chance of winning, i.e have a non-zero probability of winning the championship. You have been asked to find all such players.

Input
The first line contains one integer t (1≤t≤104) — the number of test cases. Then t test cases follow.
The first line of each test case consists of one positive integer n (1≤n≤2⋅105) — the number of players in the championship.
The second line of each test case contains n positive integers a1,a2,…,an (1≤ai≤109) — the number of tokens the players have.
It is guaranteed that the sum of n over all test cases does not exceed 2⋅105.

Output
For each test case, print the number of players who have a nonzero probability of winning the championship. On the next line print the numbers of these players in increasing order. Players are numbered starting from one in the order in which they appear in the input.

Example
input
2
4
1 2 4 3
5
1 1 1 1 1
output
3
2 3 4
5
1 2 3 4 5

题意:有n个运动员,每场比赛随机抽取两人,token数多的人获胜,,输的人的token全部给胜者,同时自己的token清零。最后拥有非零token的人为胜者。问有多少运动员有机会获胜。
我们容易看出如果暴力去判断每一个人的话,是两层循环o(n2)的复杂度,超时。我们想,是不是有些玩家不需要判断,例如,某玩家被判断有机会赢得冠军,那么token数大于等于此玩家的玩家,都有机会赢得冠军,因此,我们只需要找的有机会赢得冠军,并且token数最少的那位玩家即可。

Code:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 1e6;
int t,a,b;
void solve() {int n;scanf("%d",&n);vector<pair<int,int> > per;//储存玩家的token数量和idfor(int i=1; i<=n; i++) {int token;scanf("%d",&token);per.push_back(make_pair(token,i));}sort(per.begin(),per.end());//按first(token)排序int l=0,r=n-1,mid;while(l<r) {mid = (l+r)/2;ll k=0;for(int i=0; i<=mid; i++)k+=per[i].first;bool f=0;for(int i=mid+1; i<n; i++) {if(k<per[i].first) {f=1;break;}k +=per[i].first;}if(!f) r=mid; //keyelse l=mid+1;}vector<int> ans;//大于等于r的都有机会拿第一 for(int i=r; i<n; i++) {ans.push_back(per[i].second);}sort(ans.begin(),ans.end());cout<<ans.size();putchar('\n');for(int i=0; i<ans.size(); i++)printf("%d ",ans[i]);putchar('\n');}
int main() {cin>>t;while(t--)solve();return 0;
}

D. Permutation Transformation

main idea:(笛卡尔树)

input
3
5
3 5 2 1 4
1
1
4
4 3 1 2
output
1 0 2 3 1
0
0 1 3 2

这题我看B站学到的,自己看的时候题都没看明白啥意思哈哈。本题和笛卡尔树有点关系。不太了解笛卡尔树的点这里 click here.然后我们有这个背景知识了以后,应该好理解这题的意思了。
题目大意给你一个permutation,然后依次找到这个排列里最大元素,第一次找的的本排列中最大元素的位置,然后此位置的深度复制为0,以后深度依次加一,然后以这个元素的位置为分界点,向左右两侧的区间里找最大元素,深度为1,然后继续迭代下去,一直进行到所有元素的位置被标记即结束。还不太理解的话,在看题目中给的样例模拟的过程就差不多了。

Code:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=110;
int n;
int a[maxn],ans[maxn];
void f(int l,int r,int d) {if(l>r) return;int max_pos = max_element(a + l,a + r + 1) - a;//最大元素在数组中的位置ans[max_pos] = d;f(l,max_pos-1,d+1);f(max_pos+1,r,d+1);
}
void solve() {int n;scanf("%d",&n);for(int i=1; i<=n; i++)scanf("%d",&a[i]);f(1,n,0);for(int i=1; i<=n; i++)printf("%d ",ans[i]);putchar('\n');
}
int main() {int t;cin>>t;while(t--) {solve();}return 0;
}

G. Old Floppy Drive

main idea:二分,数学

Polycarp was dismantling his attic and found an old floppy drive on it. A round disc was inserted into the drive with n integers written on it.
Polycarp wrote the numbers from the disk into the a array. It turned out that the drive works according to the following algorithm:
the drive takes one positive number x as input and puts a pointer to the first element of the a array;
after that, the drive starts rotating the disk, every second moving the pointer to the next element, counting the sum of all the elements that have been under the pointer. Since the disk is round, in the a array, the last element is again followed by the first one;
as soon as the sum is at least x, the drive will shut down.
Polycarp wants to learn more about the operation of the drive, but he has absolutely no free time. So he asked you m questions. To answer the i-th of them, you need to find how many seconds the drive will work if you give it xi as input. Please note that in some cases the drive can work infinitely.
For example, if n=3,m=3, a=[1,−3,4] and x=[1,5,2], then the answers to the questions are as follows:
the answer to the first query is 0 because the drive initially points to the first item and the initial sum is 1.
the answer to the second query is 6, the drive will spin the disk completely twice and the amount becomes 1+(−3)+4+1+(−3)+4+1=5.
the answer to the third query is 2, the amount is 1+(−3)+4=2.

Input
The first line contains one integer t (1≤t≤104) — the number of test cases. Then t test cases follow.
The first line of each test case consists of two positive integers n, m (1≤n,m≤2⋅105) — the number of numbers on the disk and the number of asked questions.
The second line of each test case contains n integers a1,a2,…,an (−109≤ai≤109).
The third line of each test case contains m positive integers x1,x2,…,xm (1≤x≤109).
It is guaranteed that the sums of n and m over all test cases do not exceed 2⋅105.
Output
Print m numbers on a separate line for each test case. The i-th number is:
−1 if the drive will run infinitely;
the number of seconds the drive will run, otherwise.

Example
inputCopy
3
3 3
1 -3 4
1 5 2
2 2
-2 0
1 2
2 2
0 1
1 2
outputCopy
0 6 2
-1 -1
1 3

题意:给你一个数组长度为n,然后有一个指针从第一个元素开始向后移动,数组的最后一个元素紧连着数组的第一个元素,依次循环下去,给你m次询问,每次询问一个数X,问你在何时第一次前面所有走过的元素总和大于等于X,如果存在输出此时的时间,否则输出-1;

我们找到一个d(每次循环结束后,对下次一循环所贡献的值) 与 ma数组(非递减的前缀和),类似于数列的公差。然后通过d建立起两个循环之间的联系,将你需要查找的数X,缩小到第一个循环内,然后二分ma数组找到第一个大于等于转化后的 X '.
Code:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 2e5+10;
int n,m;
ll a[N],ma[N];
void solve() {int n,m;scanf("%d%d",&n,&m);ma[0]=0;//初始化 ll sum=0;//前缀和for(int i=1; i<=n; i++) {scanf("%lld",&a[i]);sum+=a[i];ma[i]=max(ma[i-1],sum);//保证有序 }ll d = sum;//公差while(m--) {ll ans=0;int x;scanf("%d",&x);if(ma[n]<x&&d<=0) {printf("-1 ");continue;}ll round;if(x<=ma[n]) round=0;else round=(x-ma[n]-1) / d + 1;x -= round*d;ans += round*n;int l=1,r=n;while(l<r) {//二分求第一个大于等于转换后x的位置int mid=(l+r)/2;if(ma[mid]>=x) r=mid;else l=mid+1;}ans+=l;printf("%lld ",ans-1);}putchar('\n');
}
int main() {int t;scanf("%d",&t);while(t--) {solve();}return 0;
}

以上思路学习于b站大佬,如有问题,小白尽力解答

Codeforces Round #702 (Div. 3)相关推荐

  1. Codeforces Round #702 (Div. 3)解题报告

    Codeforces Round #702 (Div. 3) 全部题解 读错题意,写了半天真是心态爆炸,总的来看这次题目不难的. A. Dense Array http://codeforces.co ...

  2. Codeforces Round #702 (Div. 3)A-G题解

    Codeforces Round #702 (Div. 3)A-G题解 比赛链接:https://codeforces.ml/contest/1490 这场F读错题意白给一发,G二分的if(dp[mi ...

  3. Codeforces Round #702 (Div. 3)全部题解

    题目链接:https://codeforces.com/contest/1490 文章目录 A. Dense Array B. Balanced Remainders C. Sum of Cubes ...

  4. (复习次数:1)D - Permutation Transformation——Codeforces Round #702 (Div. 3)

    https://codeforces.com/contest/1490/problem/D 一手递归 终结:没有子树 继续:把最大的找到,为记录,为界,加层数,左范围,右范围 #include< ...

  5. Codeforces Round #702 (Div. 3)——B

    链接:https://codeforces.com/contest/1490 解析:此题的思路很简单,分别算出C0.C1.C2的值,最终使C0=C1=C2=n/3即可 注意:C0只能+1,即C0转化为 ...

  6. Codeforces Round #702 (Div. 3)---C. Sum of Cubes 两种方法 cbrt()函数应用

    文章目录 题目 思路 代码 题目 题目链接 思路 思路一. 容易联想到枚举所有x存在的情况,用map映射.因为a取值在1e4上. 1e8的时间复杂度枚举,但是map具有自动排序 费时间,炸了. uno ...

  7. Codeforces Round #702 (Div. 3) C. Sum of Cubes

    题意: 你得到一个正整数 x.检查数字 x 是否可以表示为两个正整数的立方和. 正式地,您需要检查是否有两个整数 a 和 b (1≤a,b) 使得 a^3+b^3=x. 例如,如果 x=35,则数字 ...

  8. Codeforces Round #702 (Div. 3)ABCEF

    A. Плотный массив ограничение по времени на тест2 секунды ограничение по памяти на тест256 мегабайт ...

  9. Codeforces Round #702 (Div. 3)补题

    题目链接 文章目录 A. Dense Array B. Balanced Remainders C. Sum of Cubes D. Permutation Transformation E. Acc ...

最新文章

  1. Linux系统配置交换分区
  2. Sencha Touch2 -- 11.1:定义具有关联关系的模型
  3. 深度解读:都是顶薪为什么浓眉远超卡哇伊?
  4. C# MD5摘要算法、哈希算法
  5. 节约内存:Instagram的Redis实践(转)
  6. python 数字大小排序_python list字符按数字大小排序
  7. 安卓10.0内测版现新版手势操作:很实用
  8. jsessionid 在谷歌一直变_谷歌相册也要收费,这次我全靠这些云盘救命
  9. 记一次绕过安全狗与360艰难提权
  10. 初级软考程序员不会c语言,初级程序员考试就这么简单
  11. haproxy代理https配置方法【转】
  12. mongodb java 内嵌文档_MongoDB 内嵌文档
  13. 基于Stanford Parser 及OpenNLP Shallow Parser构建句子语法解析树
  14. 计算机上的科学计算器在哪里找,计算机的计算器在哪 自己的电脑上的计算器在哪里找...
  15. 微信小程序H5预览页面框架
  16. Python3,WIFI 万(破) 能 (解) 钥 (神) 匙 (器)的 GUI版本来了,果断收藏。
  17. u盘图片损坏怎么恢复
  18. 中国空气质量在线监測分析平台
  19. CDH spark启动spark-shell报错:Permission denied: user=root, access=WRITE, inode=/user
  20. who are you-实验吧1

热门文章

  1. AWS、阿里云、Azure 云计算三巨头的“混战”
  2. 黑客系列-木马又现木马
  3. [Matlab]切比雪夫Ⅰ型滤波器设计:低通、高通、带通和带阻(2)
  4. 计算机组成原理(微课版) -- 第三章 -- 运算方法与运算器
  5. WEB数据库管理平台kb-dms:数据源权限配置【八】
  6. html插入flash时钟,自制FLASH时钟代码生成器和flash音画html代码在线生成器
  7. python遗传算法VRP硬时间窗(毕设纪念)
  8. 临商银行罗庄支行能耗监测系统的应用
  9. linux 车载导航源代码,基于Linux的嵌入式车载导航系统的设计
  10. 在Cadence16.6中导入Logo