首页 > 其他分享 >Codeforces Round 900 (Div. 3)

Codeforces Round 900 (Div. 3)

时间:2024-02-20 15:02:22浏览次数:29  
标签:900 int tree Codeforces long dat Div segment define

题目

A.

只要k出现过就是YES

#include <bits/stdc++.h>
using namespace std;

#define int long long
const int N=1e5+10;
#define inf 0x3f3f3f3f

void solve() {
    int n,k;cin>>n>>k;
    map<int,int>mp;
    for(int i=0,x;i<n;i++){
        cin>>x;
        mp[x]++;
    }
    if(mp[k])cout<<"YES\n";
    else cout<<"NO\n";
}

signed main(){
    ios::sync_with_stdio(false);
    cin.tie(0);cout.tie(0);
    int left=1;
    cin>>left;
    while(left--){
        solve();
    }
}

B.

暴力即可,先一直在想规律,一直想不出来

#include <bits/stdc++.h>
using namespace std;

#define int long long
const int N=2e5+10;
#define inf 0x3f3f3f3f

int dp[N];
void solve() {
    int n;cin>>n;
    for(int i=1;i<=n;i++)cout<<dp[i]<<' ';
    cout<<'\n';
}

signed main(){
    ios::sync_with_stdio(false);
    cin.tie(0);cout.tie(0);
    dp[1]=10;dp[2]=11;
    for(int i=3;i<N;i++){
        for(int j=dp[i-1]+1;;j++){
            if((j*3)%(dp[i-1]+dp[i-2])!=0){
                dp[i]=j;
                break;
            }
        }
    }
    int left=1;
    cin>>left;
    while(left--){
        solve();
    }
}

C.

判x在最小k个数和最大k个数之间即可

#include <bits/stdc++.h>
using namespace std;

#define int long long
const int N=2e5+10;
#define inf 0x3f3f3f3f

void solve() {
    int n,k,x;cin>>n>>k>>x;
    int pre=k*(k+1)/2,pos=0;
    int l=n-k+1;
    pos=(l+n)*(k/2);
    if(k%2)pos+=n-k/2;
    if(pre<=x&&pos>=x)cout<<"YES\n";
    else cout<<"NO\n";
}

signed main(){
    ios::sync_with_stdio(false);
    cin.tie(0);cout.tie(0);
    int left=1;
    cin>>left;
    while(left--){
        solve();
    }
}

D.

暴力会超时
一个很重要的点是注意到它在每个区间内翻转是对称翻转的
也就是翻转的对象唯一
也就是这个点处于奇数个翻转区间,那么最终结果是翻转对象,
处于偶数个翻转区间,最终结果不变
用了个线段树处理

#include <bits/stdc++.h>
using namespace std;

#define int long long
const int N=2e5+10;
#define inf 0x3f3f3f3f

struct SegmentTree{
    int l,r;//标号i的元素所表示的区间左右端点
    int dat;//根据需要可改变,这里是区间求和
    int add;//懒标记
}segment_tree[N*4];//开4倍空间
void build(int p,int l,int r){//建树
    segment_tree[p].l=l;segment_tree[p].r=r;
    if(l==r){
        // segment_tree[p].dat=a[l];
        //区间长度为1,这里可进行初始化
        return ;
    }
    int mid=(l+r)/2;
    build(p*2,l,mid);
    build(p*2+1,mid+1,r);
    segment_tree[p].dat=segment_tree[p*2].dat+segment_tree[p*2+1].dat;
    //求和
}
//调用入口:build(1,1,n); 编号从1开始,区间为1-n
void change(int p,int x,int v){//单点修改,p是当前编号,x是要修改的编号,v是修改的值
    if(segment_tree[p].l==segment_tree[p].r){
        segment_tree[p].dat=v;//修改
        return ;
    }
    int mid=(segment_tree[p].l+segment_tree[p].r)/2;
    if(x<=mid)change(p*2,x,v);
    else change(p*2+1,x,v);
    segment_tree[p].dat=segment_tree[p*2].dat+segment_tree[p*2+1].dat;
}
//调用入口:change(1,x,v);

//调用入口:ask(1,l,r);
void spread(int p){//用懒标记
    if(segment_tree[p].add){//该懒标记还未用
        segment_tree[p*2].dat+=segment_tree[p].add*(segment_tree[p*2].r-segment_tree[p*2].l+1);
        segment_tree[p*2+1].dat+=segment_tree[p].add*(segment_tree[p*2+1].r-segment_tree[p*2+1].l+1);
        //给左右子节点打懒标记
        segment_tree[p*2].add+=segment_tree[p].add;
        segment_tree[p*2+1].add+=segment_tree[p].add;
        segment_tree[p].add=0;//清除p的懒标记
    }
}
void segment_change(int p,int l,int r,int d){//区间修改
    if(l<=segment_tree[p].l&&segment_tree[p].r<=r){
        segment_tree[p].dat+=d*(segment_tree[p].r-segment_tree[p].l+1);
        segment_tree[p].add+=d;//打标记
        return ;
    }
    spread(p);//下放标记
    int mid=(segment_tree[p].l+segment_tree[p].r)/2;
    if(l<=mid)segment_change(p*2,l,r,d);
    if(r>mid)segment_change(p*2+1,l,r,d);
    segment_tree[p].dat=segment_tree[p*2].dat+segment_tree[p*2+1].dat;
}
//调用入口:change(1,l,r,d);将区间l-r加d
//调用入口:ask(1,l,r);获取l-r的和
int ask(int p,int l,int r){//区间查询
    if(l<=segment_tree[p].l&&segment_tree[p].r<=r){
        return segment_tree[p].dat;
    }
    spread(p);//若用懒标记,则取消注释
    int mid=(segment_tree[p].l+segment_tree[p].r)/2;
    int sum=0;
    if(l<=mid)sum+=ask(p*2,l,r);
    if(r>mid)sum+=ask(p*2+1,l,r);
    return sum;
}
void solve() {
    int n,k;cin>>n>>k;
    build(1,1,n);
    vector<pair<int,int>>v(k+1);
    string s;cin>>s;s=" "+s;
    map<int,int>mp;
    for(int i=1;i<=k;i++)cin>>v[i].first;
    for(int i=1;i<=k;i++){
        cin>>v[i].second;
        mp[v[i].second]=i;
    }

    int q;cin>>q;
    vector<int>x(q+1);
    for(int i=1;i<=q;i++)cin>>x[i];
    sort(x.begin()+1,x.begin()+1+q);
    for(int i=1;i<=q;i++){
        auto it=mp.lower_bound(x[i]);
        int p=it->second;
        int l=v[p].first,r=v[p].second;
        int st=min(x[i],l+r-x[i]),en=max(x[i],l+r-x[i]);
        //cout<<"st="<<st<<' '<<"en="<<en<<'\n';
        segment_change(1,st,en,1);
    }
    for(int i=1;i<=k;i++){
        int l=v[i].first,r=v[i].second;
        for(int j=l;j<=r;j++){
            int cnt=ask(1,j,j);
            //if(cnt&1)cout<<"r-j+1="<<r-j+1<<'\n';
          //  else cout<<j<<'\n';
            if(cnt&1)cout<<s[l-1+r-j+1];
            else cout<<s[j];
     //       cout<<"cnt="<<cnt<<'\n';
        }
    }
    cout<<'\n';
    for(int i=1;i<=n*4;i++){
        segment_tree[i].l=0;
        segment_tree[i].r=0;
        segment_tree[i].dat=0;
        segment_tree[i].add=0;

    }
}

signed main(){
    ios::sync_with_stdio(false);
    cin.tie(0);cout.tie(0);
    int left=1;
    cin>>left;
    while(left--){
        solve();
    }
}

E.

无脑线段树做了,直接求区间与+二分

#include <bits/stdc++.h>
using namespace std;

#define int long long
const int N=2e5+10;
#define inf 0x3f3f3f3f

vector<int>a(N);
struct SegmentTree{
    int l,r;//标号i的元素所表示的区间左右端点
    int dat;//根据需要可改变,这里是区间求和
    int add;//懒标记
}segment_tree[N*4];//开4倍空间
void build(int p,int l,int r){//建树
    segment_tree[p].l=l;segment_tree[p].r=r;
    if(l==r){
         segment_tree[p].dat=a[l];
         //cout<<a[l]<<'\n';
        //区间长度为1,这里可进行初始化
        return ;
    }
    int mid=(l+r)/2;
    build(p*2,l,mid);
    build(p*2+1,mid+1,r);
    segment_tree[p].dat=segment_tree[p*2].dat&segment_tree[p*2+1].dat;
    //cout<<"p*2="<<segment_tree[p*2].dat<<' '<<"p*2+1="<<segment_tree[p*2+1].dat<<' '<<segment_tree[p].dat<<'\n';
    //求和
}
//调用入口:build(1,1,n); 编号从1开始,区间为1-
//调用入口:change(1,x,v);
int ask(int p,int l,int r){//区间查询
    if(l<=segment_tree[p].l&&segment_tree[p].r<=r){
        return segment_tree[p].dat;
    }
    //spread(p);//若用懒标记,则取消注释
    int mid=(segment_tree[p].l+segment_tree[p].r)/2;
    int sum_1=-1,sum_2=-1;
    if(l<=mid)sum_1=ask(p*2,l,r);
    if(r>mid)sum_2=ask(p*2+1,l,r);
    //cout<<"sum_1="<<sum_1<<' '<<"sum_2="<<sum_2<<'\n';

    //cout<<"Sum="<<sum<<'\n';
    if(sum_1==-1)return sum_2;
    if(sum_2==-1)return sum_1;
    return (sum_2&sum_1);
}
//调用入口:change(1,l,r,d);将区间l-r加d
//调用入口:ask(1,l,r);获取l-r的和

void solve() {
    int n;cin>>n;
    for(int i=1;i<=n;i++)cin>>a[i];
    build(1,1,n);
    int q;cin>>q;
    while(q--){
        int st,k;cin>>st>>k;
        int l=st,r=n,mid;
        int ans=-1;
        while(l<=r){
            mid=(l+r)/2;
            //cout<<"st="<<st<<' '<<"mid="<<mid<<'\n';
            //cout<<"tmp="<<ask(1,st,mid)<<'\n';
            if(ask(1,st,mid)>=k){
                //cout<<"mid="<<mid<<' '<<"st-1="<<st-1<<'\n';
                //cout<<"tmp="<<(pre_yu[mid]|pre_huo[st-1])<<'\n';
                l=mid+1;
                ans=max(ans,mid);
            }
            else r=mid-1;
        }
        cout<<ans<<' ';
    }
    cout<<'\n';

}

signed main(){
    ios::sync_with_stdio(false);
    cin.tie(0);cout.tie(0);
    int left=1;
    cin>>left;
    while(left--){
        solve();
    }
}

标签:900,int,tree,Codeforces,long,dat,Div,segment,define
From: https://www.cnblogs.com/wwww-/p/18019171

相关文章

  • Codeforces Round 928 (Div. 4) (小白的复盘)
    A.VladandtheBestofFive思路:给你一个长度字符串只包含A和B输出最多的字符解法:按题意来Code:#include<bits/stdc++.h>usingnamespacestd;intmain(){intt;cin>>t;while(t--){strings;cin>>s;intcnt=0;fo......
  • Codeforces Round 928 (Div. 4)(A、B、C、D、E、G)
    目录ABCDEGA统计A、B输出#include<bits/stdc++.h>#defineintlonglong#definerep(i,a,b)for(inti=(a);i<=(b);++i)#definefep(i,a,b)for(inti=(a);i>=(b);--i)#definepiipair<int,int>#definelllonglong#definedbdouble#de......
  • Codeforces Round 928 (Div. 4)
    总结一下最近:感觉过于追求进度了,没有好好的把每题都吃透消化,然后有点依赖题解了,没有好好的思考...B.VladandShapesB题输入二维数组的时候不可以直接两个for循环然后cin,要读入char,再转为数字赋值给二维数组,因为他读入的时候不带有空格而int是要有空格的,这样子比如读000就把它......
  • Codeforces Round 924 (Div. 2)
    目录写在前面ABCDEF写在最后写在前面比赛地址:https://codeforces.com/contest/1928。终于把欠下的一堆题补上了呃呃天使骚骚共通线什么构式呃呃,一周目就想走老师线直通单身笑死我了。A签到。发现等分后重新拼接可以得到\(\frac{x}{2}\times2y\)与\(\frac{y}{2}\times2......
  • Codeforces Round 927 (Div. 3)(A~F)
    目录ABCDEFA第一个遇到连续两个荆棘的地方就不能再赢金币了。所以统计连续两个荆棘之前的所有金币#include<bits/stdc++.h>#defineintlonglong#definerep(i,a,b)for(inti=(a);i<=(b);++i)#definefep(i,a,b)for(inti=(a);i>=(b);--i)#definepiipai......
  • Codeforces Round 927 (Div. 3)
    CodeforcesRound927(Div.3)A-ThornsandCoins解题思路:出现连续两个障碍之前,所有金币都能拿到。代码:#include<bits/stdc++.h>usingnamespacestd;usingll=longlong;usingpii=pair<ll,ll>;#definefifirst#definesesecondusingi128=__int128_t;......
  • D. Divisible Pairs
    原题链接题解如果\((a_i+a_j)\mod\x==0\)那么\((a_i\mod\x+a_j\mod\x)\mod\x==0\)如果\((a_i-a_j)\mod\y==0\)那么\(a_i\mod\y==a_j\mod\y\)所以我们可以把每个\(a\)的求模情况存下来,\(a[i]\)的贡献为其前面的\(a\)出现的对应求模情况数量\(co......
  • Codeforces Round 927 (Div. 3)
    CodeforcesRound927(Div.3)C.LR-remaindersDescription给定一个长度为\(n\)的数组\(a\)和\(n\)个指令,每条指令为\(\texttt{L,R}\)中的一种。依次处理每个指令:首先,输出\(a\)中所有元素的乘积除以\(m\)的余数。然后,如果当前指令为\(\textttL\),则移除数组......
  • Codeforces Round 927 (Div. 3)
    A传送门  根据题意每一步只能走一步或者两步,很显然如果有连续的两个荆棘就不能走了,在不能走之前是一定可以把路上的金币全捡起来所以只需要边捡金币边判断是否能继续走下即可。#include<bits/stdc++.h>usingll=longlong;typedefstd::pair<int,int>PII;typedef......
  • Codeforces Round 923 (Div. 3)
    A.MakeitWhite#include<bits/stdc++.h>usingnamespacestd;usingi32=int32_t;usingi64=longlong;usingi128=__int128;usingldb=longdouble;#defineinti64usingvi=vector<int>;usingpii=pair<int,int>;usingvii......