j-甜甜圈(第十三届icpc河南省赛)
Posted yeah17981
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了j-甜甜圈(第十三届icpc河南省赛)相关的知识,希望对你有一定的参考价值。
照常,上题目:J-甜甜圈_河南省第十三届ICPC大学生程序设计竞赛(重现赛) (nowcoder.com)
这种题,就一眼能看出来直接模拟肯定是不行的了
然后比赛的时候三个人就思考了下人生决定跳过
咳咳正经题解来了
每次移动的是一个区间,区间可以联想得到树状数组(奇怪的联想增加了!)
想象一下,把两叠甜甜圈的顶端相对
图有点随意大家将就点
然后相当于有个每次只能移动一格的指针,然后跳来跳去每次取出当前最大的甜甜圈
我们考虑建一个数组(脑子里)此时此位置有甜甜圈为1,没有为0
每次移动的步数就是指针位置和最大甜甜圈位置这个区间的数组的和
这不就是树状数组擅长的嘛
(然后有个b忘了longlong结果wa了还是队友发现的,十年oi一场空不写ll见祖宗)
管你听没听到,看就完了
#include <bits/stdc++.h>
using namespace std;
int n,m;
int a[200005],c[400005]; //对应原数组和树状数组
int b[200005], vis[6000007];
int lowbit(int x){
return x&(-x);
}
void updata(int i,int k){ //在i位置加上k
while(i <= n){
c[i] += k;
i += lowbit(i);
}
}
int getsum(int i){ //求A[1 - i]的和
int res = 0;
while(i > 0){
res += c[i];
i -= lowbit(i);
}
return res;
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
int n1,n2;
cin>>n1>>n2;
n=n1+n2;
for(int i=n1;i>=1;i--)
{
updata(i,1);
cin>>a[i];b[i]=a[i];vis[a[i]]=i;
}
for(int i=n1+1;i<=n1+n2;i++)
{
updata(i,1);
cin>>a[i];b[i]=a[i];vis[a[i]]=i;
}
int flag1=n1,flag2,sum=0;
sort(b+1,b+n+1);//
m=n;
while(m)
{
flag2=vis[b[m]];//甜甜圈位置
if(flag2==flag1||flag2==flag1+1)
{
updata(flag2,-1);
if(flag2==flag1) flag1--;
}
else
if(flag2>flag1)
{
sum+=getsum(flag2-1)-getsum(flag1);
flag1=flag2-1;
updata(flag2,-1);
}
else
{
sum+=getsum(flag1)-getsum(flag2);
flag1=flag2-1;
updata(flag2,-1);
}
m--;
}
cout<<sum<<"\\n";
}
以上是关于j-甜甜圈(第十三届icpc河南省赛)的主要内容,如果未能解决你的问题,请参考以下文章