[置顶] HDU 4046 Panda (分块 或 线段树区间合并)
2016-10-31 22:52
423 查看
题面挺美的
题意:给出一个字符串,两种操作1.询问区间[l,r]内wbw有多少个(可重叠)2.将位置x的字符改为c
题解:分块和线段树都可以搞,分块很好解释,只需要单独处理边界问题。线段树区间合并需要将每次询问的区间拿出来单独处理一次。
分块:
线段树:
题意:给出一个字符串,两种操作1.询问区间[l,r]内wbw有多少个(可重叠)2.将位置x的字符改为c
题解:分块和线段树都可以搞,分块很好解释,只需要单独处理边界问题。线段树区间合并需要将每次询问的区间拿出来单独处理一次。
分块:
#include<cstring> #include<string> #include<iostream> #include<queue> #include<cstdio> #include<algorithm> #include<map> #include<cstdlib> #include<cmath> #include<vector> //#pragma comment(linker, "/STACK:1024000000,1024000000"); using namespace std; #define INF 0x3f3f3f3f #define maxn 50005 int n,m; int num,block,l[maxn],r[maxn],belong[maxn]; char s[maxn]; int ans[maxn]; int solve(int x,int y) { int sum=0; for(int i=x;i<=y-2;i++) { if(s[i]=='w'&&s[i+1]=='b'&&s[i+2]=='w') sum++; } return sum; } void init() { block=sqrt(n); num=n/block; if(n%block) num++; for(int i=1;i<=n;i++) { belong[i]=(i-1)/block+1; } for(int i=1;i<=num;i++) { l[i]=(i-1)*block+1; r[i]=i*block; } r[num]=n; for(int i=1;i<=num;i++) { ans[i]=solve(l[i],r[i]); } } void update(int x,char c) { s[x]=c; ans[belong[x]]=solve(l[belong[x]],r[belong[x]]); } int query(int x,int y) { if(belong[x]==belong[y]) { return solve(x,y); } int sum=0; sum+=solve(x,r[belong[x]]); for(int i=belong[x]+1;i<=belong[y];i++) { if(i!=belong[y]) sum+=ans[i]; sum+=solve(max(x,l[i]-2),min(y,l[i]+1)); } sum+=solve(l[belong[y]],y); return sum; } int main() { int ca=1; int T; scanf("%d",&T); while(T--) { scanf("%d%d",&n,&m); scanf("%s",s+1); init(); printf("Case %d:\n",ca++); while(m--) { int op; scanf("%d",&op); if(op==0) { int a,b; scanf("%d%d",&a,&b); a++,b++; printf("%d\n",query(a,b)); } else { int a; char c[3]; scanf("%d%s",&a,c); a++; update(a,c[0]); } } } return 0; }
线段树:
#include<cstring> #include<string> #include<iostream> #include<queue> #include<cstdio> #include<algorithm> #include<map> #include<cstdlib> #include<cmath> #include<vector> //#pragma comment(linker, "/STACK:1024000000,1024000000"); using namespace std; #define INF 0x3f3f3f3f char s[50005]; int sum[200005]; int Merge(int l,int r) { int mid=l+r>>1; int sum=0; for(int i=max(mid-1,l);i<=mid;i++) { if(i+2>r) break; if(s[i]=='w'&&s[i+1]=='b'&&s[i+2]=='w') sum++; } return sum; } void init(int l,int r,int k) { if(l==r) { sum[k]=0; return ; } int mid=l+r>>1; init(l,mid,k<<1); init(mid+1,r,k<<1|1); sum[k]=sum[k<<1]+sum[k<<1|1]+Merge(l,r); } void update(char c,int d,int l,int r,int k) { if(l==d&&r==d) { s[l]=c; return ; } int mid=l+r>>1; if(d<=mid) update(c,d,l,mid,k<<1); else update(c,d,mid+1,r,k<<1|1); sum[k]=sum[k<<1]+sum[k<<1|1]+Merge(l,r); } vector<pair<int ,int> >vec; int query(int s,int t,int l,int r,int k) { if(s==l&&r==t) { vec.push_back(pair<int ,int>(s,t)); return sum[k]; } int mid=l+r>>1; if(t<=mid) return query(s,t,l,mid,k<<1); else if(s>mid) return query(s,t,mid+1,r,k<<1|1); else return query(s,mid,l,mid,k<<1)+query(mid+1,t,mid+1,r,k<<1|1); } int main() { int T,ca=1; scanf("%d",&T); while(T--) { int n,m; scanf("%d%d",&n,&m); scanf("%s",s+1); s[0]='#'; s[n+1]='#'; s[n+2]='#'; init(1,n,1); printf("Case %d:\n",ca++); while(m--) { int op; scanf("%d",&op); if(op==0) { int a,b; scanf("%d%d",&a,&b); a++; b++; vec.clear(); int ans=query(a,b,1,n,1); for(int i=0;i<vec.size()-1;i++) { int x=vec[i].second; for(int j=max(vec[i].first,x-1);j<=x;j++) { if(j+2>b) break; if(s[j]=='w'&&s[j+1]=='b'&&s[j+2]=='w') ans++; } } printf("%d\n",ans); } else { int a; char str[3]; scanf("%d%s",&a,str); a++; update(str[0],a,1,n,1); } } } return 0; }
相关文章推荐
- hdu 4046 Panda 线段树 单点修改 求区间010个数
- hdu 4046 Panda (线段树,单点更新,区间求和)
- hdu_4046 Panda线段树_点修改_区间求和
- hdu 4046 Panda (线段树 单点更新 区间查询)
- HDU 4351 Digital root 线段树区间合并
- HDU 4718 The LCIS on the Tree (树链剖分+线段树区间合并)
- hdu 1540 & poj 2892 Tunnel Warfare 线段树区间合并
- HDU 1540 POJ 2892 线段树区间合并
- HDU 1540 Tunnel Warfare (线段树,区间合并)
- M - Sequence operation HDU - 3397 线段树,成段更新,区间合并)
- hdu 1199 Color the Ball (线段树区间合并,离散化)
- HDU 3308 - LCIS(线段树+区间合并)
- hdu 4046 Panda [线段树]
- HDU 3397 - Sequence operation(线段树+区间合并)
- hdu 3308 线段树区间合并
- HDU - 4553 线段树区间合并
- hdu 3308 LCIS 最大连续递增字串长 线段树区间合并
- HDU 3911 线段树区间合并、异或取反操作
- [HDU 3308]LCIS[线段树][区间合并]
- HDU 1540 Tunnel Warfare 线段树:单点更新,区间合并