hdu 4339 线段树+二分
来源:互联网 发布:基础编程入门教程 编辑:程序博客网 时间:2024/09/21 09:02
本人此方法很搓。。。大多数人的做法和我不一样,时间比我快一倍。这道题是一个非常好的题,首先是他的数据量非常大,这就提示我们要做一些优化。。而本题又是在字符串的基础上设计算法,字符串有很多细节还是必须要注意的。。题意很简单,这里略掉。拿到两个字符串后,首先是圈定线段树的宽度,即两个字符串长度的最短值,不再范围内的字符不会影响结果。接下来就是如何处理query,把两个字符串相减后发现,所求的即从i后最多有多少连续个0。怎么办?貌似用最直接的方法做很费劲,而且不保险,二分!!!求最大点,计算quary,每个线段节点的值等于它的左子树和右子树的值取或。。附带码:
#include <iostream>#include <cmath> using namespace std;#define clear(a) memset(a,0,sizeof(a))#define lson l,m,rt<<1#define rson m+1,r,rt<<1|1 const int N=1001000;int sum[N<<2],a[N],k,n,n0;char s1[N],s2[N];void pushup(int rt){ sum[rt]=sum[rt<<1]||sum[rt<<1|1];}void build(int l,int r,int rt){ if (l==r) { ++k; sum[rt]=a[k]; return; } int m=(l+r)>>1; build(lson); build(rson); pushup(rt);}int query(int L,int R,int l,int r,int rt){ if (L<=l&&r<=R) { return sum[rt]; } int m=(l+r)>>1,res=0; if (L<=m) res=res||query(L,R,lson); if (R>m) res=res||query(L,R,rson); return res; }void find(int p,int l,int r){ if (r-l<=1) { if (s1[r-1]==s2[r-1]) printf("%d\n",r-p+1); else printf("%d\n",l-p+1); } else { int m=(l+r)/2; if (query(p,m,1,n,1)) find(p,l,m-1); else find(p,m,r); }}void update(int p,int add,int l,int r,int rt){ if (l==r) { sum[rt]=add; return; } int m=(l+r)>>1; if (p<=m) update(p,add,lson); else update(p,add,rson); pushup(rt); }int main(){ int T,i,l1,l2,m,j; scanf("%d",&T); for (j=1;j<=T;j++) { scanf("%s",s1); scanf("%s",s2); clear(a); clear(sum); l1=strlen(s1); l2=strlen(s2); if (l1>l2) n=l1; else n=l2; n0=l1+l2-n; for (i=1;i<=n;i++) { if (i<l1&&i<l2) a[i]=s1[i-1]-s2[i-1]; else if (i>l1) a[i]=-(s2[i-1]-'a'+1); else a[i]=s1[i-1]-'a'+1; } k=0; build(1,n,1); printf("Case %d:\n",j); scanf("%d",&m); while (m--) { int x,y,z,add; scanf("%d",&z); if (z==2) { scanf("%d",&x); if (x>=n0||s1[x]!=s2[x]) printf("%d\n",0); else find(x+1,x+1,n0); } else { scanf("%d%d",&x,&y); char c,ch; scanf("%c%c",&c,&ch); if (x==1) { add=ch-s2[y]; if (add^a[y+1]) update(y+1,add,1,n,1); s1[y]=ch; } else { add=s1[y]-ch; if (add^a[y+1]) update(y+1,add,1,n,1); s2[y]=ch; } a[y+1]=add; } } } return 0;}
- hdu 4339 线段树+二分
- hdu 4339 线段树+二分
- hdu 4614 线段树+二分~
- HDU 4614 线段树+二分
- HDU 4791二分+线段树
- HDU - 4973(线段树+二分)
- hdu 4614 线段树+二分
- hdu 5592 线段树 + 二分
- HDU 3450 线段树+二分
- hdu 4614 线段树+二分
- HDU 5649 (二分 线段树)
- HDU 6070 二分+线段树
- hdu 6070二分+线段树
- HDU 4614 线段树+二分
- HDU 5649 线段树+二分
- hdu 4339 Query(线段树+二分,4级)
- hdu 4737 线段树维护+二分
- hdu - 4747 - Mex(二分+线段树)
- windows 服务安装脚本
- libxml 解析xml文档
- hdu1404 Digital Deletions------SG
- hdu 4002 收获非常大的一个题 多功能大数模板的应用
- 清华梦的粉碎—写给清华大学的退学申请 /王垠
- hdu 4339 线段树+二分
- maven 仓库文件配置3
- .NET async await 关键字最简单例子
- Java菜鸟进阶篇(一)
- jxl生成EXCEL
- FAT VFAT (FAT32) NTFS有什么区别?
- Andriod学习笔记4——AndroidManifest.xml分析
- 浅析JVM
- 创建透明的UIToolbar