码迷,mamicode.com
首页 > 其他好文 > 详细

CodeChef January Challenge Queries on the StringSolved

时间:2015-01-04 22:57:32      阅读:218      评论:0      收藏:0      [点我收藏+]

标签:

只能说太弱了。。。 别人眼中的水题。。 我到现在还不知道能不能写出~~

维护前缀和并且应用同余定理: (sum[r] - sum[l-1])%3 == 0 -> (sum[r]%3 - sum[l-1]%3)%3 == 0 -> sum[r]%3 == sum[l-1]%3

线段树维护前缀和中0,1,2的个数即可;

 

发来kuangbin巨的代码;

#include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <string>
#include <math.h>
#include <stdlib.h>
#include <time.h>
using namespace std;
const int MAXN = 100010;
struct Node{
int l,r;
int c[3];
int add;
}segTree[MAXN<<2];
void Update_Add(int i,int val){
int cc[3];
for(int j = 0;j < 3;j++)cc[j] = segTree[i].c[(j-val+3)%3];
for(int j = 0;j < 3;j++)segTree[i].c[j] = cc[j];
segTree[i].add += val;
segTree[i].add %= 3;
}
void push_up(int i){
for(int j = 0;j < 3;j++)
segTree[i].c[j] = segTree[i<<1].c[j]+segTree[(i<<1)|1].c[j];
}
void push_down(int i){
if(segTree[i].add){
Update_Add(i<<1,segTree[i].add);
Update_Add((i<<1)|1,segTree[i].add);
segTree[i].add = 0;
}
}
int a[MAXN],b[MAXN];
void build(int i,int l,int r){
segTree[i].l = l;
segTree[i].r = r;
for(int j = 0;j < 3;j++)
segTree[i].c[j] = 0;
segTree[i].add = 0;
if(l == r){
segTree[i].c[b[l]]++;
return;
}
int mid = (l+r)/2;
build(i<<1,l,mid);
build((i<<1)|1,mid+1,r);
push_up(i);
}
void update(int i,int l,int r,int val){
if(val == 0)return;
if(segTree[i].l == l && segTree[i].r == r){
Update_Add(i,val);
return;
}
push_down(i);
int mid = (segTree[i].l + segTree[i].r)/2;
if(r <= mid)update(i<<1,l,r,val);
else if(l > mid)update((i<<1)|1,l,r,val);
else {
update(i<<1,l,mid,val);
update((i<<1)|1,mid+1,r,val);
}
push_up(i);
}
int query(int i,int l,int r,int c0){
if(segTree[i].l == l && segTree[i].r == r)
return segTree[i].c[c0];
push_down(i);
int mid = (segTree[i].l + segTree[i].r)/2;
if(r <= mid)return query(i<<1,l,r,c0);
else if(l > mid)return query((i<<1)|1,l,r,c0);
else {
return query(i<<1,l,mid,c0)+query((i<<1)|1,mid+1,r,c0);
}
}
char str[MAXN];
int main(){
int n,m;
while(scanf("%d%d",&n,&m) == 2){
scanf("%s",str);
b[0] = 0;
n++;
a[1] = b[1] = 0;
for(int i = 2;i <= n;i++){
a[i] = str[i-2]-0;
b[i] = (b[i-1]+a[i])%3;
}
build(1,1,n);
while(m--){
int op;
scanf("%d",&op);
if(op == 1){
int x,y;
scanf("%d%d",&x,&y);
x++;
update(1,x,n,(y-a[x]+3)%3);
a[x] = y;
}
else {
int x,y;
scanf("%d%d",&x,&y);
y++;
long long ans = 0;
int tmp = query(1,x,y,0);
ans += (long long)tmp*(tmp-1)/2;
tmp = query(1,x,y,1);
ans += (long long)tmp*(tmp-1)/2;
tmp = query(1,x,y,2);
ans += (long long)tmp*(tmp-1)/2;
cout<<ans<<endl;
}
}
}
}

 

CodeChef January Challenge Queries on the StringSolved

标签:

原文地址:http://www.cnblogs.com/ltwy/p/4202292.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!