ARC088简要题解
作者:互联网
我直接一个痛苦面具
E题做了一整年
F感觉就是NOIP2018D1T3把我送退役那玩意,没时间写了,坑着吧。
C题:
从L开始,每次乘2
#include<bits/stdc++.h>
using namespace std;
long long X, Y;
int n;
int main() {
cin>>X>>Y;
int cnt = 1;
long long nval = X;
while(nval <= Y)
cnt++, nval *= 2;
cout<<cnt-1;
return 0;
}
D题:
这D感觉和平时的D画风不是很一样,还卡了一小会。
可以想到,如果你把整个串给搞成一样的了,不管他是全0还是全1,都算完成任务,因为最后一步的代价是
∣
S
∣
|S|
∣S∣,不会使得答案变小。
看到区间反转,直接拿来差分。
然后就相当于把所有差分出来为1的东西给整没。
我们发现,直接改到头尾好像很优秀,因为这样在消除一个1的同时,花的长度更长。
然后就
m
i
n
(
m
a
x
(
a
l
l
)
)
min(max(all))
min(max(all))就行了。
#include<bits/stdc++.h>
using namespace std;
int n;
char s[1231231];
int cha[200010];
int main() {
scanf("%s", s+1);
int n = strlen(s+1);
for(int i=1;i<=n;++i)
if(s[i] != s[i-1])
cha[i] = 1;
int ans = n;
for(int i=1;i<=n;++i) {
if(cha[i])
ans = min(ans, max(n - i + 1, i-1));
}
cout<<ans;
return 0;
}
E题:
搞了一年。
玩了一会儿,想到了策略:先遇到的尽量往外甩,特判必须在中间的元素。简单证明一下这个肯定最优:
只考虑两对,对于
X
X
Y
Y
XXYY
XXYY,谁在外面无所谓
对于
X
Y
X
Y
XYXY
XYXY,谁在外面无所谓
对于
X
Y
Y
X
XYYX
XYYX,X在外面更优
然后就进入了奇妙的推下标环节,痛苦30min之后发觉没救,他这下标区间减是打在移动后的区间上的,如果我不及时更新他移动后的样子,那就没啥救,而及时更新就直接
O
(
n
2
)
O(n^2)
O(n2)
然后想起了前两天备课的时候的一个习题的结论:把第一个排列通过交换相邻两个元素的方式,搞成另外某个排列,这玩意需要的次数是逆序对个数。
然后编个号,特判一下中间奇数,映射一下,BIT逆序对。
可以说做的是非常酸爽。
#include<bits/stdc++.h>
using namespace std;
int n;
char s[200010];
vector<int>loc[1010];
int lef[1010], rig[1010];
int ton[1010];
namespace BIT {
#define low(k) ((k) & (-k))
int a[200010];
inline void add(int pos) {
for(int i = pos; i <= n; i += low(i))
a[i] += 1;
return;
}
inline int query(int k) {
int ret = 0;
for(int i = k; i > 0; i -= low(i))
ret += a[i];
return ret;
}
inline int Q(int L, int R) {
if(L > R)
return 0;
int ret = 0;
ret += query(R);
ret -= query(L - 1);
return ret;
}
} using namespace BIT;
pair<int, int>sth[500010];
int scnt;
int trans[500010];
int vis[500010];
int main() {
scanf("%s", s+1);
n = strlen(s+1);
for(int i = 1; i <= n; ++i) {
loc[s[i]].push_back(i);
ton[s[i]]++;
}
int jcnt = 0;
for(int i = 'a'; i <= 'z'; ++i) {
if(ton[i] % 2)
jcnt++;
}
if(n % 2 == 0 && jcnt > 0) {
printf("-1");
return 0;
}
if(n % 2 == 1 && jcnt > 1) {
printf("-1");
return 0;
}
for(int i='a'; i <= 'z'; ++i)
rig[i] = loc[i].size() - 1;
int spe = 0;
for(int i=1;i<=n;++i) {
int nw = s[i];
if(vis[i])
continue;
if(i == loc[nw][rig[nw]]) {
spe = i;
continue;
}
sth[++scnt] = make_pair(i, loc[nw][rig[nw]]);
vis[i] = vis[loc[nw][rig[nw]]] = 1;
rig[nw]--;
}
sort(sth + 1, sth + scnt + 1);
int nwlef = 0, nwrig = n + 1;
for(int i=1;i<=scnt;++i) {
trans[sth[i].first] = ++nwlef;
trans[sth[i].second] = --nwrig;
}
if(spe)
trans[spe] = n + 1 >> 1;
// for(int i=1;i<=n;++i)
// printf("%d", trans[i]);
long long ans = 0;
for(int i=1;i<=n;++i) {
ans += Q(trans[i] + 1, n);
add(trans[i]);
}
cout<<ans;
return 0;
}
// aacddeebb
// cccaacdd
// acddeebbca
// acdeebbdca
// acdebb
F题:
感觉B和NOIP2018D1T3没啥差别。
没时间了就没写,也不太想写,咕这儿吧。
感觉这两天上午人是蒙的,状态贼差。
标签:简要,return,int,题解,sth,ret,ARC088,trans,nw 来源: https://blog.csdn.net/weixin_43977362/article/details/118756849