AtCoder Regular Contest 068(缺d)
\(AT\_arc068\_a\)
https://www.luogu.com.cn/problem/AT_arc068_a
题解:来回选取\(5,6\)两面最优,直接计算即可。
#include <bits/stdc++.h>
#define int long long
using namespace std;
signed main(){
int x;
cin >> x;
cout << x/11*2+((x%11)>=1)+((x%11)>=7) << endl;
return 0;
}
\(AT\_arc068\_b\)
https://www.luogu.com.cn/problem/AT_arc068_b
题解:假设每种牌都留一张,记录每种牌多余数量,发现多余数量和为奇数,则答案减一。
#include <bits/stdc++.h>
using namespace std;
const int N=1e5+10;
int n;
int buc[N];
int main(){
cin >> n;
for(int i=1; i<=n; i++){
int x;
cin >> x;
buc[x]++;
}
int res=0,ans=0;
for(int i=1; i<=1e5; i++)
if(buc[i]){
ans++;
if(buc[i]%2==0) res++;
}
if(res%2) ans--;
cout << ans << endl;
return 0;
}
\(AT\_arc068\_c\)
https://www.luogu.com.cn/problem/AT_arc068_c
题解:考虑枚举\(d\),按规则跳,每次跳到一个格子累加其被覆盖次数,但发现这样做是错的,因为可能在一个区间内跳多次,贡献重复计算。
考虑如下性质:
\(1\):若\(d\leq r-l+1\),则此区间一定被跳到,考虑从\(l-1\)跳到\(r+1\)需要\(r-l+2\)即证。
\(2\):若\(d>r-l+1\),则此区间至多只会被跳一次,考虑从\(l\)跳\(r-l+2\)步会到\(r+2\)即证。
于是将区间按区间长度从小到大排序,并从小到大枚举\(d\),直接累加\(d\leq r-l+1\)区间的答案,对于\(d>r-l+1\)的区间,由于不会被重复跳,直接用树状数组统计每个点被覆盖次数即可。
#include <bits/stdc++.h>
using namespace std;
const int N=1e5+10;
int n,m;
struct Segment{
int l,r,len;
bool operator <(Segment t){
return len<t.len;
}
}seg[3*N];
struct BitTree{
int tr[N];
int lowbit(int x){
return x&-x;
}
void modify(int k,int x){
for(int i=k; i<=n; i+=lowbit(i)) tr[i]+=x;
}
int query(int k){
int res=0;
for(int i=k; i; i-=lowbit(i)) res+=tr[i];
return res;
}
}tree;
int main(){
cin >> m >> n;
for(int i=1; i<=m; i++){
int l,r;
cin >> l >> r;
seg[i]={l,r,r-l+1};
}
sort(seg+1,seg+m+1);
for(int d=1,j=1; d<=n; d++){
while(j<=m&&seg[j].len<d){
tree.modify(seg[j].l,1);
tree.modify(seg[j].r+1,-1);
j++;
}
int ans=m-j+1;
for(int i=d; i<=n; i+=d) ans+=tree.query(i);
cout << ans << endl;
}
return 0;
}
\(AT\_arc068\_d\)
https://www.luogu.com.cn/problem/AT_arc068_d