codeforces2补题报告

A. How Much Does Daytona Cost?
我们定义了一个最常见整数:它在该子段中出现的次数大于该子段中任何其他整数出现的次数。(数组的子数段是a数组中元素的连续数段)
给定一个大小为n的数组 和一个整数 ,判断a中是否存在一个非空子段,其中k是最常见整数。

输入描述
每个测试由多个测试用例组成。第一行包含一个整数 t( t<=1000) - 测试用例的个数。测试用例说
明如下。
每个测试用例的第一行包含两个整数n和k(1<=n<=100,1<=k<=100)-数组中的元素个数和
最常见整数。
每个测试用例的第二行包含 个整数 a1-an - 数组中的元素。
输出描述
对于每个测试用例,如果存在以 为最常见整数的子段,则输出 "是",否则输出 "否"。
您可以输出任何情况下的答案(例如,字符串 "yEs"、"yes"、"Yes "和 "YES "将被识别为肯定答案)

若它在该子段中出现的次数大于该子段中任何其他整数出现的次数,则只需判断它是否存在。

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. typedef long long int LL;
  4. LL a[101000],c[1010000],n,m,ans,l,r,t;
  5. int main(){
  6. cin>>t;
  7. while(t--){
  8. memset(c,0,sizeof(c));
  9. cin>>n>>m;
  10. for(int i=0;i<n;i++){
  11. cin>>a[i];
  12. c[a[i]]=1;
  13. }
  14. if(c[m]){
  15. cout<<"Yes"<<endl;
  16. }
  17. else{
  18. cout<<"No"<<endl;
  19. }
  20. }
  21. }

B.Aleksa 和 Stack

塞尔维亚信息学奥林匹克竞赛结束后,阿莱克萨非常伤心,因为他没有获得奖牌(同时他不知道奖牌的数量),所以瓦西里耶来给他出了一道简单的题,让他的心情好起来。
瓦西里耶给了阿莱克萨一个正整数 (  ),让他构造一个大小为 的正整数严格递增数组,使得
对于每个 ( 
 ), 不能被 整除.
请注意,大小为 的严格递增数组 是一个数组,其中每个 ( 
 ) 都有
由于阿莱克萨认为自己现在是个糟糕的程序员,他请你帮他找到这样一个数组。
输入描述
每个测试由多个测试用例组成。第一行包含一个整数 ( 
 ) - 测试用例的个数。测试用例说
明如下。
每个测试用例的第一行包含一个整数 ( 
 ) - 数组中元素的个数。
保证所有测试用例的 之和不超过 。、
输出描述
对于每个测试用例,输出 个整数

)。
可以证明任何 都存在解。如果存在多个解,则输出其中任意一个。

先打表,后解决问题

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. typedef long long int LL;
  4. LL a[2010000],c[1010000],n,m,ans,l,r,t;
  5. int main(){
  6. a[1]=2;
  7. a[2]=3;
  8. for(int i=3;i<=2e5;i++){
  9. l=a[i-1]+a[i-2];
  10. for(int j=a[i-1]+1;;j++){
  11. if(j*3%l!=0){
  12. a[i]=j;
  13. break;
  14. }
  15. }
  16. }
  17. cin>>t;
  18. while(t--){
  19. cin>>n;
  20. for(int i=1;i<=n;i++){
  21. cout<<a[i]<<" ";
  22. }
  23. cout<<endl;
  24. }
  25. }

C.Vasilije in Cacak
Aca 和 Milovan 是两位厉害的程序员,他们决定给 Vasilije 出一道难题来测试他的技能。
给 Vasilije 三个正整数: 、 和 ,他必须判断能否在 和 之间选择 个不同的整数,使它们的和等于 。
由于 Vasilije现在在塞尔维亚最奇怪的城市Cacak,也就是Aca和Milovan居住的地方,所以他觉得这个问题很奇怪。所以他需要你的帮助来解决这个问题。
输入描述
第一行包含一个整数 ( 
 ) - 测试用例的数量。
每个测试用例的唯一一行包含三个整数 、 和 ( 
 , 
 , 
 )-
-他可以选择的最大元素、可以选择的元素个数以及必须达到的总和。
请注意,所有测试用例的 之和可能超过 。
输出描述
每个测试用例输出一行:如果可以在 和 之间选择 个不同的整数,使它们的和等于 ,则输出"YES";如果不可能,则输出 "NO"。

把不可能的情况排除掉,1+...+k>x||n-k+1+...+n<x;

否则正确;

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. typedef long long int LL;
  4. LL a[2010000],c[1010000],n,m,ans,l,r,t;
  5. int main(){
  6. for(int i=1;i<=2e5;i++){
  7. a[i]=i+a[i-1];
  8. }
  9. cin>>t;
  10. while(t--){
  11. cin>>n>>m>>l;
  12. if((n-m+1+n)*m/2<l||(1+m)*m/2>l){
  13. cout<<"NO"<<endl;
  14. }
  15. else{
  16. cout<<"YES"<<endl;
  17. }
  18. }
  19. }

D.Reverse Madness
给你一个长度为 的字符串 ,其中包含小写拉丁字母。
接下来会给你一个正整数 和两个长度为 的数组 和 。
保证这两个数组满足以下条件:
 ;
 ;
 , 对于每个正整数 ,

 , 对于每个正整数 ,如

现在给你一个正整数 ,表示你需要对 进行修改的次数。
每个修改都用一个正整数 来定义:
找出一个索引 ,使得 (注意这样的 是唯一的)。



将 的子串从索引 反转到索引 。
反转字符串 的子串 意味着使 等于

完成最后一次修改后,打印 。
输入描述
每个测试包含多个测试用例。第一行包含一个整数 ( 
 ) - 测试用例的数量。测试用例说明
如下。
每个测试用例的第一行包含两个整数 和 (
)--字符串 的长度以及数组 和
的长度。
每个测试用例的第二行包含拉丁字母小写字符串 (  ) - 初始字符串。
每个测试用例的第三行包含 个正整数
( )--数组 。
每个测试用例的第四行包含 个正整数
 (  ) --数组 。
每个测试用例的第五行包含一个正整数 ( 
 ) --需要对 进行修改的次数。
每个测试用例的第六行包含 个正整数
。(  ) - 修改说明。
保证所有测试用例中 的总和不超过 。
保证所有测试用例的 之和不超过 。
保证声明中的条件对数组 和 成立。
输出描述
针对每个测试用例,在新的一行中输出最后一次修改后的字符串 。

做的时候因反转时间复杂度太大,后来已明白。

因为这是一个反转问题,所以反转意味着修改区间值,于是用了差分;

最后将s[j-1]与s[l[i]+r[i]-j-1]交换即可;

#include<bits/stdc++.h>
typedef long long int ll;
using namespace std;
ll n,m,a[1010000],c[1010000],t,x,q,o,v[1010000],l[1010000],r[1010000];
char s[1010000];
map<ll,ll>mp;
map<ll,ll>p;
int main(){
    cin>>t;
    while(t--){
        p.clear();
        mp.clear();
        scanf("%d%d",&n,&m);
        scanf("%s",s);
        for(int i=1;i<=m;i++){
            scanf("%d",&l[i]);
        }
        for(int i=1;i<=m;i++){
            scanf("%d",&r[i]);
            for(int j=l[i];j<=r[i];j++){
                mp[j]=i;
            }
        }
        cin>>q;
        for(int i=0;i<q;i++){
            cin>>x;
            int a1=min(x,r[mp[x]]+l[mp[x]]-x);
            int b1=max(x,r[mp[x]]+l[mp[x]]-x);
            p[a1]++;
            p[b1+1]--;
        }
        for(int i=1;i<=n;i++){
            p[i]+=p[i-1];
        }
        for(int i=1;i<=m;i++){
            for(int j=l[i];j<=(l[i]+r[i])>>1;j++){
                if(p[j]%2==1){
                    swap(s[j-1],s[l[i]+r[i]-j-1]);
                }
            }
        }
        printf("%s\n",s);
    }
    return 0;
}
 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值