CF527

CF527A

每次操作相当于让a减b 显然 \(ab\) 交换前次数为 \(a/b\) 然后a剩下 \(a\bmod b\)
类似辗转相除 复杂度 \(O(\log a)\)

点击查看代码
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define inl inline
#define int ll
#define endl '\n'
#define gc getchar
#define pc putchar
const int N=2e5+5;
const int M=6e5+5;
const int inf=0x7fffffff;
const int mod=1e9+7;
inl int read(){
    int x=0,f=1;char c=gc();
    while(c<'0'||c>'9'){if(c=='-')f=-1;c=gc();}
    while(c>='0'&&c<='9'){x=(x<<1)+(x<<3)+(c^48);c=gc();}
    return x*f;
}
inl void write(int x){
    if(x<0){pc('-');x=-x;}
    if(x>9)write(x/10);
    pc(x%10+'0');
}
inl void writei(int x){write(x);pc(' ');}
inl void writel(int x){write(x);pc('\n');}
int n,m,rt,ans;
signed main(){
    ios::sync_with_stdio(0);
    cin.tie(0),cout.tie(0);
    int a=read(),b=read();
    while(b){
        ans+=a/b;
        a%=b;
        if(a<b)swap(a,b);
    }
    cout<<ans<<endl;
    return 0;
}

CF527B

题面翻译:给定两个长为 \(n\) 的字符串 令 \(x\) 为两字符串相同位置上字母不同的个数
我们可以交换第一个串中任意两个字母(可以不交换)
\(x\) 的最小值以及方案

显然 扫一遍求出不换的贡献后 考虑是否有两个位置 分别为{x,y}和{y,x}的形式 那么ans-2
否则找两个串所有失配的字母中相同的 有则ans-1
否则就是不换也行

CF527C

简单线段树题。
可以发现 答案为长和宽中最长连续段乘起来 这个可以用线段树快速维护
每个节点维护左侧最长、右侧最长、区间最长连续段。
信息维护显然。

点击查看代码
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define inl inline
#define int ll
#define endl '\n'
#define gc getchar
#define pc putchar
const int N=2e5+5;
const int M=6e5+5;
const int inf=0x7fffffff;
const int mod=1e9+7;
inl int read(){
    int x=0,f=1;char c=gc();
    while(c<'0'||c>'9'){if(c=='-')f=-1;c=gc();}
    while(c>='0'&&c<='9'){x=(x<<1)+(x<<3)+(c^48);c=gc();}
    return x*f;
}
inl void write(int x){
    if(x<0){pc('-');x=-x;}
    if(x>9)write(x/10);
    pc(x%10+'0');
}
inl void writei(int x){write(x);pc(' ');}
inl void writel(int x){write(x);pc('\n');}
int w,h,n;
struct segment_tree{
    int ma[N<<2],lma[N<<2],rma[N<<2],vis[N<<2];
    #define ls k<<1
    #define rs k<<1|1
    #define mid (l+r>>1)
    inl void build(int k,int l,int r){
        ma[k]=lma[k]=rma[k]=r-l+1;
        if(l==r)return;
        build(ls,l,mid);build(rs,mid+1,r);
    }
    inl void modify(int k,int l,int r,int x){
        vis[k]=1;
        rma[k]=min(rma[k],r-x);
        lma[k]=min(lma[k],x-l+1);
        if(l==r)return;
        if(x<=mid)modify(ls,l,mid,x);
        else modify(rs,mid+1,r,x);
        ma[k]=max(max(ma[ls],ma[rs]),rma[ls]+lma[rs]);
    }
}W,H;
signed main(){
    ios::sync_with_stdio(0);
    cin.tie(0),cout.tie(0);
    cin>>w>>h>>n;
    W.build(1,1,w);H.build(1,1,h);
    while(n--){
        char c;int x;
        cin>>c>>x;
        if(c=='H')H.modify(1,1,h,x);
        else W.modify(1,1,w,x);
        cout<<H.ma[1]*W.ma[1]<<endl;
    }
    return 0;
}

CF527D

去绝对值 设 \(l_i=x_i-w_i\) \(r_i=x_i+w_i\) 那么对于 \(x_j\ge x_i\) 需要满足 \(l_j\ge r_i\) 才连边
那么就是求最多不覆盖线段数 贪心求解

点击查看代码
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define inl inline
#define int ll
#define getchar cin.get
#define endl '\n'
#define gc getchar
#define pc putchar
const int N=2e5+5;
const int M=6e5+5;
const int inf=0x7fffffff;
const int mod=1e9+7;
inl int read(){
    int x=0,f=1;char c=gc();
    while(c<'0'||c>'9'){if(c=='-')f=-1;c=gc();}
    while(c>='0'&&c<='9'){x=(x<<1)+(x<<3)+(c^48);c=gc();}
    return x*f;
}
inl void write(int x){
    if(x<0){pc('-');x=-x;}
    if(x>9)write(x/10);
    pc(x%10+'0');
}
inl void writei(int x){write(x);pc(' ');}
inl void writel(int x){write(x);pc('\n');}
int n,t,res;
struct node{
    int l,r;
    friend bool operator<(node a,node b){return a.r^b.r?a.r<b.r:a.l<b.l;}
}a[N];
signed main(){
    ios::sync_with_stdio(0);
    cin.tie(0),cout.tie(0);
    n=read();
    for(int i=1;i<=n;i++){
        int x=read(),w=read();
        a[i]={x-w,x+w};
    }
    sort(a+1,a+n+1);
    int r=-inf;
    for(int i=1;i<=n;i++){
        if(a[i].l<r)continue;
        res++;r=a[i].r;
    }
    cout<<res<<endl;
    return 0;
}

CF527E

发现要求入度出度都是偶数 满足欧拉路径要求
那么跑欧拉路径要求入度出度为偶数 只需要每走一条边换个方向即可
注意 \(m\) 为奇数情况 需要加个自环
菊花图复杂度会被卡到 \(O(nm)\) 注意每条边只会被走一次 可以将head一起增加

点击查看代码
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define inl inline
#define int ll
#define getchar cin.get
#define endl '\n'
#define gc getchar
#define pc putchar
const int N=1e6+5;
const int M=6e5+5;
const int inf=0x7fffffff;
const int mod=1e9+7;
inl int read(){
    int x=0,f=1;char c=gc();
    while(c<'0'||c>'9'){if(c=='-')f=-1;c=gc();}
    while(c>='0'&&c<='9'){x=(x<<1)+(x<<3)+(c^48);c=gc();}
    return x*f;
}
inl void write(int x){
    if(x<0){pc('-');x=-x;}
    if(x>9)write(x/10);
    pc(x%10+'0');
}
inl void writei(int x){write(x);pc(' ');}
inl void writel(int x){write(x);pc('\n');}
int n,m,vis[N],deg[N],k;
vector<int>v;
vector<pair<int,int>>e;
int head[N],nxt[N],to[N],cnt=1;
inl void add(int u,int v){
    nxt[++cnt]=head[u];
    to[cnt]=v;
    head[u]=cnt;
}
inl void dfs(int x){
    for(int &i=head[x];i;i=nxt[i]){
        if(vis[i])continue;
        vis[i]=vis[i^1]=1;
        int y=to[i];
        dfs(y);
        e.push_back((++k)&1?make_pair(x,y):make_pair(y,x));
    }
}
signed main(){
    ios::sync_with_stdio(0);
    cin.tie(0),cout.tie(0);
    n=read();m=read();
    for(int i=1;i<=m;i++){
        int u=read(),v=read();
        add(u,v);add(v,u);
        deg[u]++;deg[v]++;
    }
    for(int i=1;i<=n;i++)
        if(deg[i]&1)v.push_back(i);
    for(int i=0;i<v.size();i+=2){
        add(v[i],v[i+1]);add(v[i+1],v[i]);
        deg[v[i]]++;deg[v[i+1]]++;m++;
    }
    if(m&1)add(1,1);
    dfs(1);
    cout<<e.size()<<endl;
    for(auto i:e)
        cout<<i.first<<' '<<i.second<<endl;
    return 0;
}
posted @ 2023-12-01 17:31  xiang_xiang  阅读(5)  评论(0编辑  收藏  举报