bzoj 1552(splay)

1552: [Cerc2007]robotic sort

Time Limit: 5 Sec   Memory Limit: 64 MB
Submit: 681   Solved: 278
[ Submit][ Status][ Discuss]

Description

Input

输入共两行,第一行为一个整数N,N表示物品的个数,1<=N<=100000。第二行为N个用空格隔开的正整数,表示N个物品最初排列的编号。

Output

输出共一行,N个用空格隔开的正整数P1,P2,P3…Pn,(1 < = Pi < = N),Pi表示第i次操作前第i小的物品所在的位置。 注意:如果第i次操作前,第i小的物品己经在正确的位置Pi上,我们将区间[Pi,Pi]反转(单个物品)。

Sample Input

6
3 4 5 1 6 2

Sample Output

4 6 4 5 6 6


解题思路:splay的裸题,每个点记入下它子树的最小值,然后splay维护翻转和选择区间


#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
int n,sum,ug,mx,root;
int a[110000];
int zhi[110000],dui[110000],pan[110000],qo[110000],size[110000],fa[110000],l[110000],r[110000],rever[110000];
int po[110000],q[110000];


inline int read()
{
char y; int x=0,f=1; y=getchar();
while (y<'0' || y>'9') {if (y=='-') f=-1; y=getchar();}
while (y>='0' && y<='9') {x=x*10+int(y)-48; y=getchar();}
return x*f;
}


void build(int &x,int lg,int rg,int f)
 {
  int mid=(lg+rg)/2;
  x=mid;
  zhi[mid]=a[mid]; dui[mid]=mid; pan[mid]=mid; qo[mid]=zhi[mid]; size[mid]=rg-lg+1; fa[mid]=f;
  if (lg==rg) return;
    if (lg<=mid-1) build(l[x],lg,mid-1,mid);
    if (mid+1<=rg) build(r[x],mid+1,rg,mid);
    int u; if (qo[l[x]]<qo[r[x]]||(qo[l[x]]==qo[r[x]] && dui[pan[l[x]]]<dui[pan[r[x]]])){u=pan[l[x]];}else u=pan[r[x]];
    if (qo[u]<qo[pan[mid]] || (qo[u]==qo[pan[mid]] && dui[u]<dui[pan[mid]]))
     {
      pan[mid]=u; qo[mid]=qo[u];
}
 }
 
void pushdown(int now)
{
if (rever[now]==1)
{
rever[now]^=1; 
if (l[now]!=0) rever[l[now]]^=1;
if (r[now]!=0) rever[r[now]]^=1;
swap(l[now],r[now]);

 }  


void find(int now,int zhi)
 {
  pushdown(now);
  if (zhi==now)
  {
  sum+=size[l[now]]+1;
  return;
 }
if (pan[l[now]]==zhi)
     {
      find(l[now],zhi);
}else
 {
  sum+=size[l[now]]+1;
  find(r[now],zhi);
 }
 } 
 
int find1(int now,int sug)
 {
  pushdown(now);
  if (sug==size[l[now]]+1) return now;
  if (sug>size[l[now]]+1) return find1(r[now],sug-size[l[now]]-1);else return find1(l[now],sug);
 }


 
void maindown(int now)
 {
  size[now]=size[l[now]]+size[r[now]]+1;
  pan[now]=now; qo[now]=zhi[now];
  int u; if (qo[pan[l[now]]]<qo[pan[r[now]]]||(qo[pan[l[now]]]==qo[pan[r[now]]] && dui[pan[l[now]]]<dui[pan[r[now]]])){u=pan[l[now]];}else u=pan[r[now]];
    if (qo[u]<qo[pan[now]] || (qo[u]==qo[pan[now]] && dui[u]<dui[pan[now]]))
     {
      pan[now]=u; qo[now]=qo[u];
}
  } 
 
void rotate(int x,int &mu) 
 {
  int y=fa[x]; int z=fa[y];
  if (y==mu) mu=x;else
  {
  if (l[z]==y) l[z]=x; else r[z]=x;
 }
fa[y]=x; fa[x]=z;
if (l[y]==x)
{
fa[r[x]]=y; l[y]=r[x]; r[x]=y; 
}else
 {
   fa[l[x]]=y; r[y]=l[x]; l[x]=y; 
 }
    maindown(y); maindown(x);
 }
 
void splay(int x,int &mu)
 {
  int now=x; int tail=0;
  while(now!=mu)
  {
  ++tail; q[tail]=now; now=fa[now];
 } pushdown(now);
for (int i=tail;i>=1;--i) pushdown(q[i]);
  while (x!=mu)
  {
  int y=fa[x]; int z=fa[y];
  if (y!=mu)
  {
    if (l[y]==x ^ l[z]==y) rotate(x,mu);else
 rotate(y,mu); 
}
rotate(x,mu);
}
 }
 
int main()
{
n=read(); a[1]=0x7fffffff; a[n+2]=0x7fffffff; a[0]=0x7fffffff; qo[0]=0x7fffffff; 
for (int i=1;i<=n;++i)
{
a[i+1]=read();
}
n=n+2;
build(root,1,n,0);
for (int i=1;i<=n-2;++i)
{
if (i==n-2)
{
printf("%d",n-2);
return(0);
}
ug=find1(root,i);
splay(ug,root); 
sum=0; 
find(root,pan[r[root]]); ug=find1(root,sum+1);
printf("%d ",sum-1);
splay(ug,r[root]);
splay(pan[r[root]],l[r[root]]);
rever[l[r[root]]]^=1;
}
}

内容概要:本文详细介绍了如何利用Simulink进行自动代码生成,在STM32平台上实现带57次谐波抑制功能的霍尔场定向控制(FOC)。首先,文章讲解了所需的软件环境准备,包括MATLAB/Simulink及其硬件支持包的安装。接着,阐述了构建永磁同步电机(PMSM)霍尔FOC控制模型的具体步骤,涵盖电机模型、坐标变换模块(如Clark和Park变换)、PI调节器、SVPWM模块以及用于抑制特定谐波的陷波器的设计。随后,描述了硬件目标配置、代码生成过程中的注意事项,以及生成后的C代码结构。此外,还讨论了霍尔传感器的位置估算、谐波补偿器的实现细节、ADC配置技巧、PWM死区时间和换相逻辑的优化。最后,分享了一些实用的工程集成经验,并推荐了几篇有助于深入了解相关技术和优化控制效果的研究论文。 适合人群:从事电机控制系统开发的技术人员,尤其是那些希望掌握基于Simulink的自动代码生成技术,以提高开发效率和控制精度的专业人士。 使用场景及目标:适用于需要精确控制永磁同步电机的应用场合,特别是在面对高次谐波干扰导致的电流波形失真问题时。通过采用文中提供的解决方案,可以显著改善系统的稳定性和性能,降低噪声水平,提升用户体验。 其他说明:文中不仅提供了详细的理论解释和技术指导,还包括了许多实践经验教训,如霍尔传感器处理、谐波抑制策略的选择、代码生成配置等方面的实际案例。这对于初学者来说是非常宝贵的参考资料。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值