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;
}