Codeforces Round #529 (Div. 3)

A  输出第1 2 4 7...位置的字母即可

#include <bits/stdc++.h>
#define fir first
#define se second
#define ll long long
#define pb push_back
#define mp make_pair
#define ull unsigned long long 
#define cl(a,b) memset(a,b,sizeof(a))
#define quickio(a) ios::sync_with_stdio(a)
#define datatest() freopen("data.in","r",stdin)
#define pii pair<int,int>  
#define pdd pair<double,double>
using namespace std;
const int maxn=2e5+10;
const int maxm=1e6+10;
const ll INF=1e12;
const ll mod=1e9+8;
const int maxblock=sqrt(1e9)+10;
int n;
char str[maxn];

int main(){
    while (~scanf("%d",&n)){
        scanf("%s",str+1);
        string ans;
        int pos=1;
        for (int i=1;i<=10;i++){
            if (pos>n) break;
            ans+=str[pos];
            pos+=i;
        }
        cout<<ans<<endl;

    }
    return 0;
}

B 只有在删掉最小/最大的那个值才会有可能更改答案 排序后只要在最小值/最大值的地方讨论即可

#include <bits/stdc++.h>
#define fir first
#define se second
#define ll long long
#define pb push_back
#define mp make_pair
#define ull unsigned long long 
#define cl(a,b) memset(a,b,sizeof(a))
#define quickio(a) ios::sync_with_stdio(a)
#define datatest() freopen("data.in","r",stdin)
#define pii pair<int,int>  
#define pdd pair<double,double>
using namespace std;
const int maxn=2e5+10;
const int maxm=1e6+10;
const ll INF=1e12;
const ll mod=1e9+8;
const int maxblock=sqrt(1e9)+10;
int n,a[maxn];

int main(){
    while (~scanf("%d",&n)){
        for (int i=1;i<=n;i++) scanf("%d",&a[i]);
        sort(a+1,a+n+1);
        int res=a[n]-a[1];
        res=min(res,a[n]-a[2]);
        res=min(res,a[n-1]-a[1]);
        printf("%d\n",res);
    }
    return 0;
}

C 枚举n的为1的二进制位,如果这时候数量不够 就把这个位*2补到下一位 直到满足条件或者所有数都拆成1


 #include <bits/stdc++.h>
#define fir first
#define se second
#define ll long long
#define pb push_back
#define mp make_pair
#define ull unsigned long long 
#define cl(a,b) memset(a,b,sizeof(a))
#define quickio(a) ios::sync_with_stdio(a)
#define datatest() freopen("data.in","r",stdin)
#define pii pair<int,int>  
#define pdd pair<double,double>
using namespace std;
const int maxn=2e5+10;
const int maxm=1e6+10;
const ll INF=1e12;
const ll mod=1e9+8;
const int maxblock=sqrt(1e9)+10;
map<int,int> ma;
int n,k;
int num=0;

int main(){
    scanf("%d %d",&n,&k);
    for (int i=0;i<30;i++){
        if (n&(1<<i)){
            ma[(1<<i)]++;
            num++;
        }
    }
    for (int i=29;i>0;i--){
        if (num>k) break;
        if (ma.count(1<<i)==0) continue;
        int temp=ma[1<<i];
        int dif=k-num;
        if (temp>dif){
            ma[1<<(i-1)]+=2*dif;
            ma[1<<i]-=dif;
            num+=dif;
        }
        else{
            ma[1<<(i-1)]+=2*temp;
            ma[1<<i]=0;
            num+=temp;
        }
    }
    if (num!=k){
        printf("NO\n");
    }
    else{
        printf("YES\n");
        for (int i=29;i>=0;i--){
            if (ma[1<<i]){
                for (int j=0;j<ma[1<<i];j++){
                    printf("%d ",(1<<i));
                }
            }
        }
        printf("\n");
    }
    return 0;
}

D 枚举第一个的情况 之后check一遍即可

#include <bits/stdc++.h>
#define fir first
#define se second
#define ll long long
#define pb push_back
#define mp make_pair
#define ull unsigned long long 
#define cl(a,b) memset(a,b,sizeof(a))
#define quickio(a) ios::sync_with_stdio(a)
#define datatest() freopen("data.in","r",stdin)
#define pii pair<int,int>  
#define pdd pair<double,double>
using namespace std;
const int maxn=2e5+10;
const int maxm=1e6+10;
const ll INF=1e12;
const ll mod=1e9+8;
const int maxblock=sqrt(1e9)+10;
int n;
int a[maxn][2];
vector<int> res;
int solve(int p1,int p2){
    res.clear();
    res.pb(1);
    res.pb(a[1][p1]);
    res.pb(a[1][p2]);
    for (int i=1;i<=n-2;i++){
       /* cout<<"i="<<i<<endl;
        for (int i=0;i<res.size();i++){
            cout<<res[i]<<" ";
        }*/
        cout<<endl;
        int pos=res[i];
        int pos1=res[i+1];
        if (a[pos][1]!=pos1&&a[pos][0]!=pos1) return 0;
        if (a[pos][1]==pos1){
            res.pb(a[pos][0]);
        }
        else{
            res.pb(a[pos][1]);
        }
    }
    int aa=res[0];
    int bb=res[1];
    int pos=res[n-1];
    if (aa==a[pos][0]&&bb==a[pos][1]) return 1;
    if (aa==a[pos][1]&&bb==a[pos][0]) return 1;
    return 0;
}
int main(){
    while (scanf("%d",&n)!=EOF){
        for (int i=1;i<=n;i++){
            scanf("%d %d",&a[i][0],&a[i][1]);
        }
        if (solve(0,1)){
            for (int i=0;i<res.size()-1;i++){
                printf("%d ",res[i]);
            }
            printf("\n");
            continue;
        }
        if (solve(1,0)){
            for (int i=0;i<res.size()-1;i++){
                printf("%d ",res[i]);
            }
            printf("\n");
            continue;
        }
        printf("NO\n");
    }
    return 0;
}

E 预处理出括号序列的前缀和之后

对于一个位置从)改成( 相当于从他开始之后的所有位置+2

所以只要判断1~i-1的最小值是否大于等于0且i到n的最小值是否大于等于-2

用线段树维护即可

(改成)是类似的

#include <bits/stdc++.h>
#define fir first
#define se second
#define ll long long
#define pb push_back
#define mp make_pair
#define ull unsigned long long 
#define cl(a,b) memset(a,b,sizeof(a))
#define quickio(a) ios::sync_with_stdio(a)
#define datatest() freopen("data.in","r",stdin)
#define pii pair<int,int>  
#define pdd pair<double,double>
using namespace std;
const int maxn=1e6+10;
const int maxm=1e6+10;
const ll INF=1e12;
const ll mod=1e9+8;
const int maxblock=sqrt(1e9)+10;
char str[maxn];
int n;
int tree[maxn<<2];
int sum[maxn];
void pushup(int rt){
    tree[rt]=min(tree[rt<<1],tree[rt<<1|1]);
}
void build(int rt,int l,int r){
    if (l==r){
        tree[rt]=sum[l];
        return ;
    }
    int mid=(l+r)>>1;
    build(rt<<1,l,mid);
    build(rt<<1|1,mid+1,r);
    pushup(rt);
}
int query(int rt,int l,int r,int L,int R){
    if (L>R){
        return 1;
    }
    int Min=1e8;
    if (l>=L&&r<=R) return tree[rt];
    int mid=(l+r)>>1;
    if (L<=mid){
        Min=min(Min,query(rt<<1,l,mid,L,R));
    }
    if (R>mid){
        Min=min(Min,query(rt<<1|1,mid+1,r,L,R));
    }
    return Min;
}
int main(){
    while (~scanf("%d",&n)){
        scanf("%s",str+1);
        sum[0]=0;
        for (int i=1;i<=n;i++){
            if (str[i]=='(')
                sum[i]=sum[i-1]+1;
            else sum[i]=sum[i-1]-1;
        }
        build(1,1,n);
        int ans=0;
        for (int i=1;i<=n;i++){
            if (str[i]=='('){
                if (sum[n]!=2) continue;
                int Min=query(1,1,n,i,n);
                int Min1=query(1,1,n,1,i-1);
                if (Min>=2&&Min1>=0){
                    //cout<<"i="<<i<<endl;
                    ans++;
                }
            }
            if (str[i]==')'){
                if (sum[n]!=-2) continue;
                int  Min=query(1,1,n,i,n);
                int Min1=query(1,1,n,1,i-1);
                if (Min>=-2&&Min1>=0){
                   // cout<<"i="<<i<<endl;
                    ans++;
                }
            }
        }
        printf("%d\n",ans);
    }
    return 0;
}

F 如果没有特殊边 显然是把a最小的点跟其他点连成一个菊花图

只要把这n-1条边跟m条边一起跑一个mst出来就可以了

#include <bits/stdc++.h>
#define fir first
#define se second
#define ll long long
#define pb push_back
#define mp make_pair
#define ull unsigned long long 
#define cl(a,b) memset(a,b,sizeof(a))
#define quickio(a) ios::sync_with_stdio(a)
#define datatest() freopen("data.in","r",stdin)
#define pii pair<int,int>  
#define pdd pair<double,double>
using namespace std;
const int maxn=2e5+10;
const int maxm=1e6+10;
const ll INF=1e12;
const ll mod=1e9+8;
const int maxblock=sqrt(1e9)+10;
struct Edge{
    int u,v;
    ll w;
};
vector<Edge> V;
int n,m;
ll a[maxn];
int cmp(Edge a,Edge b){
    return a.w<b.w;
}
int fa[maxn];
int tfind(int x){
    if (fa[x]==x) return x;
    else return fa[x]=tfind(fa[x]);
}
ll solve(){
    sort(V.begin(),V.end(),cmp);
    ll tot=0;
    ll num=0;
    for(int i=1;i<=n;i++) fa[i]=i;
    for (int i=0;i<V.size();i++){
        if (num==n-1) break;
        int u=V[i].u;
        int v=V[i].v;
        ll w=V[i].w;
        int a=tfind(u);
        int b=tfind(v);
        if (a==b) continue;
        fa[a]=b;
        tot+=w;
        num++; 
    }
    return tot;
}
int main(){
    scanf("%d %d",&n,&m);
    for (int i=1;i<=n;i++){
        scanf("%lld",&a[i]);
    }
    for (int i=1;i<=m;i++){
        int u,v;
        ll w;
        scanf("%d %d %lld",&u,&v,&w);
        V.pb(Edge{u,v,w});
    }
    int rt=-1;
    ll Min=INF;
    for (int i=1;i<=n;i++){
        Min=min(Min,a[i]);
    }
    for (int i=1;i<=n;i++){
        if (a[i]==Min){
            rt=i;
            break;
        }
    }
    for (int i=1;i<=n;i++){
        if (i==rt) continue;
        V.pb(Edge{i,rt,a[i]+a[rt]});
    }
    ll res=solve();
    printf("%lld\n",res);
    return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值