排序(sortb)

题目描述

懒得写题目背景了,就不写了。
有一个 0,1n1 的排列 p1,p2pn,如果 pipja(其中 为按位异或),你就可以交换 pipj。你希望通过若干次操作把它排序。但是,你还没有定下 a 的值,你想知道能够成功排序情况下最小的非负整数 a。
为了让题目更难,有时候会对排列进行更新,每次更新是交换某对 pipj。在每次更新后你都要需要输出最小的 a
 
第一行输入 nmm 是更新的个数。
接下来 m 行,每行两个整数 i,j,表示交换 pipj

 

 

对于所有数据,1n,m500000,对于每个更新 1i,jnij
Subtask110ptsn,m5 
Subtask220ptsn,m300 
Subtask320ptsm=1 
Subtask420ptsn,m50000 
Subtask530pts
 

solution
考虑排序1~7 的最小代价。
是4 。因为跨过4的可以让它刚好等于4
 
可以发现 2i 足够覆盖 2i+11
那么我们可以两两求出i,j交换的代价 输出所有的最大代价(也就是最高位)即可。
复制代码
 1 #include<cstdio>
 2 #include<iostream>
 3 #include<cstdlib>
 4 #include<cstring>
 5 #include<algorithm>
 6 #include<cmath>
 7 using namespace std;
 8 int n,m,p[500005],bin[22],dy[500005];
 9 int get(int v){
10     for(int i=20;i>=0;i--)if(v&(1<<i))return i;
11     return 21;
12 }
13 int main()
14 {
15     cin>>n>>m;
16     for(int i=0;i<n;i++)scanf("%d",&p[i]),dy[p[i]]=i;
17     for(int i=0;i<n;i++){
18         bin[get(i^p[i])]++;
19     }
20     for(int i=1,t1,t2;i<=m;i++){
21         
22         scanf("%d%d",&t1,&t2);
23         t1--,t2--;
24         bin[get(t1^p[t1])]--;
25         bin[get(t2^p[t2])]--;
26         swap(p[t1],p[t2]);
27         bin[get(t1^p[t1])]++;
28         bin[get(t2^p[t2])]++;
29         int fl=0;
30         for(int j=20;j>=0;j--)if(bin[j]){
31             printf("%d\n",(1<<j));fl=1;
32             break;
33         }
34         if(!fl)puts("0");
35     }
36     return 0;
37 }
View Code
复制代码

 

 
posted @   liankewei123456  阅读(170)  评论(0编辑  收藏  举报
编辑推荐:
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
点击右上角即可分享
微信分享提示