CF1090H Linearization
先考虑什么样的串才符合条件.\(s_i=P(x\&i)\oplus b\),其实这里的\(b\)只能使得整体是否取反,所以可以先不管.然后考虑\(x\)的每个二进制位的对\(s_0\)到\(s_{len-1}\)贡献,可以发现如果\(x\)从小到大第\(i\)位为\(1\),那么会给从头开始每一个长度为\(2^i\)区间的后半部分所有\(s_i\)异或上\(1\),类似于这样$$\begin{matrix}&\underbrace{0,0,...0},&\underbrace{1,1,...1},&\underbrace{0,0,...0},&\underbrace{1,1,...1}...\&2{i-1}&2{i-1}&2{i-1}&2{i-1}\end{matrix}$$
然后,根据上面的结论,不管\(x\)是多少,我们都可以发现这样的串,前半部分和后半部分要么完 全 一 致,要么完全不同,并且前半部分和后半部分也满足这个性质.
再考虑怎么求出最小操作次数.题目允许的操作是区间异或,显然可以改成两次前缀异或,还有就是两次前缀异或也可以反向合成一次区间异或.然后如果把串的差分数组搞出来\(t_i=s_i\oplus s_{i+1}\),那么一次前缀操作就是对差分数组单点取反.这个差分数组也有一定性质,因为前面说到这个串前半部分和后半部分要么完全一致要么完全不同,所以这个差分数组的前后两半(不包括中间那个点)\([1,mid)\)到\((mid,n]\)也是完全相同的,并且这两半也满足这个性质(至于中间那个点值是多少暂时不用管).用这个分治过程可以把串分成\(\log n\)层,第\(i\)层都有\(2^{i-1}\)个区间,并且每层的所有区间的中间点都要相同.所以每次把这些点找出来,然后对答案的贡献就是\(0\)个数和\(1\)个数的较小值
每次暴力统计是不行的,注意到每一层相邻两个数间距相等且为\(2^k(k>1)\),所以可以预处理出每个位置以及每次往后走\(2^k\)到达的位置的\(0/1\)个数的后缀和,然后在每一层直接找出这一层第一个中间点,用区间和贡献答案就好了
注意两次前缀操作可以合成为一次区间操作,所以应该输出\(\lceil\frac{ans}{2}\rceil\)
#include<bits/stdc++.h>
#define LL long long
#define uLL unsigned long long
#define db double
using namespace std;
const int N=2e5+10;
int rd()
{
int x=0,w=1;char ch=0;
while(ch<'0'||ch>'9') {if(ch=='-') w=-1;ch=getchar();}
while(ch>='0'&&ch<='9') {x=(x<<3)+(x<<1)+(ch^48);ch=getchar();}
return x*w;
}
char cc[N];
int n,a[N],q,sb[N][18];
int main()
{
n=rd();
scanf("%s",cc+1);
for(int i=1;i<=n;++i) a[i]=cc[i]-'0';
int lz=log2(n);
for(int j=0;j<lz;++j)
for(int i=n-1;i;--i)
sb[i][j]=(i+(1<<(j+1))<=n?sb[i+(1<<(j+1))][j]:0)+(a[i]^a[i+1]);
q=rd();
while(q--)
{
int l=rd()+1,r=rd()+1,len=r-l+1,an=0;
for(int i=len>>1,j=0;i;i>>=1,++j)
{
int ii=l+(1<<j)-1,x=sb[ii][j]-(ii+len<n?sb[ii+len][j]:0);
an+=min(x,i-x);
}
printf("%d\n",(an+1)/2);
}
return 0;
}
CF1090H Linearization的更多相关文章
- CF1090H Linearization 构造、位运算、前缀和
传送门 有点神仙的题目 首先注意到对于串\(s\),\(b=s_0\)一定会比\(b = s_0 \bigoplus 1\)更优 考虑先分析linear串的性质.注意到位运算考虑按位处理.我们考虑\( ...
- HDU 5095 Linearization of the kernel functions in SVM(模拟)
主题链接:http://acm.hdu.edu.cn/showproblem.php? pid=5095 Problem Description SVM(Support Vector Machine) ...
- Linearization of the kernel functions in SVM(多项式模拟)
Description SVM(Support Vector Machine)is an important classification tool, which has a wide range o ...
- 模拟 HDOJ 5095 Linearization of the kernel functions in SVM
题目传送门 /* 题意:表达式转换 模拟:题目不难,也好理解题意,就是有坑!具体的看测试样例... */ #include <cstdio> #include <algorithm& ...
- 控制结构(8) 线性化(linearization)
// 上一篇:管道(pipeline) // 下一篇:程序计数器(PC) "编程语言不过是一个工具,什么语言都一样","编程语言能改变人的思维,不同的语言会带给你不同的思 ...
- 控制结构(8): 线性化(linearization)
// 上一篇:管道(pipeline) // 下一篇:程序计数器(PC) "编程语言不过是一个工具,什么语言都一样","编程语言能改变人的思维,不同的语言会带给你不同的思 ...
- HDU 5095 Linearization of the kernel functions in SVM (坑水)
比较坑的水题,首项前面的符号,-1,+1,只有数字项的时候要输出0. 感受一下这些数据 160 0 0 0 0 0 0 0 0 -10 0 0 0 0 0 0 0 0 10 0 0 0 0 0 0 0 ...
- hdu 5095 Linearization of the kernel functions in SVM(模拟,分类清楚就行)
题意: INPUT: The input of the first line is an integer T, which is the number of test data (T<120). ...
- 【JUC】JDK1.8源码分析之ConcurrentLinkedQueue(五)
一.前言 接着前面的分析,接下来分析ConcurrentLinkedQueue,ConcurerntLinkedQueue一个基于链接节点的无界线程安全队列.此队列按照 FIFO(先进先出)原则对元素 ...
随机推荐
- R_Studio(学生成绩)绘制频率分布直方图、分布饼图、折线比较图
对“Gary.csv”中的成绩数据进行分布分析 (1)按0-59,60-69,70-79,80-89,90-100分组绘制高级语言程序设计成绩的频率分布直方图. (2)按0-59,60-69,70-7 ...
- Miniui 表单验证
自定义表单验证: input输入框的表单验证可通过vtype和onvalidation事件两种方式实现 可编辑列表(例如div)的表单验证只能通过vtye来实现表单验证 (1)vtype方式: jsp ...
- 一、基础篇--1.1Java基础-MVC设计思想
MVC简介: MVC(Model View Controller) 是模型(model)-视图(view)-控制器(controller)的缩写.一种软件设计典范,用一种业务逻辑.数据.界面显示分离的 ...
- mysql数据库简单补充
1.只有拥有特定权限的用户才能执行特定的操作.就好像我们在现实生活中,一般没有权利进入军事禁区,除非我们被某个很有权利并且可以指定其他人进入军事基地的人赋予了进入军事禁区的权利. 命令: GRANT ...
- 快读模板&&快出模板
inline int read() { ,b=; char c=getchar(); ') { if(c=='-') b=-; c=getchar(); } ') { a=(a<<)+(a ...
- iso-----genisoimage/md5sum命令用法
命令安装 直接yum安装即可 yum install genisoimage -y 功能说明 可将指定的目录与文件做成ISO 9660格式的映像文件,以供刻录光盘 语法 genisoimage -U ...
- DeepFaceLab错误:DLL Load failed 找不到指定模块!
这个错误不知道多少人遇到了,我反正是看到过不少次了.但是一直没有花时间去研究. 今日有空帮群友远程了一下,虽然搞了一会儿,最终还是搞定了,分享一下经验. 问题描述:在执行2号脚本,视频转图片的时候 ...
- java 传值
好文章:https://zwmf.iteye.com/blog/1738574 public class Test { public int i,j; public void test_m(Test ...
- ForkJoin使用
一.Fork Join 分而治之的办法 JDk为Fork/Join框架提供了很好的支持,我们想要用这个算法首先得创建一个Fork/Join任务,在JDK中这个任务就叫做:ForJoinTask,只要继 ...
- JavaScript日常学习4
JavaScript事件 1.<button id="btn1" onclick="document.getElementById("btn1" ...