CodeChef January Challenge Queries on the StringSolved

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

维护前缀和并且应用同余定理: (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;
}
}
}
}
时间: 2024-08-10 17:50:16

CodeChef January Challenge Queries on the StringSolved的相关文章

Codechef July Challenge 2014部分题解

Dish Owner(并查集) 链接:http://www.codechef.com/JULY14/problems/DISHOWN/ 题意分析:本题主要操作就是给出0 x y时,拥有第x道菜的厨师与拥有第y道菜的厨师pk,谁拥有的所有菜的其中一道菜(不一定是x或y)的分值比较高谁就获胜,并赢得loser的所有菜.即比较的是每个人分值最高的菜,所以对于非loser的人来说,他的分值最高的菜是不变的.综合题意用并查集易解. #include <cstdio> const int Maxn=100

Codechef October Challenge 2018 游记

Codechef October Challenge 2018 游记 CHSERVE - Chef and Serves 题目大意: 乒乓球比赛中,双方每累计得两分就会交换一次发球权. 不过,大厨和小厨用了另外一种规则:双方每累计得 K 分才会交换发球权.比赛开始时,由大厨发球. 给定大厨和小厨的当前得分(分别记为 P1 和 P2),请求出接下来由谁发球. 思路: \((P1+P2)\%K\)判断奇偶性即可. 代码链接 BITOBYT - Byte to Bit 题目大意: 在字节国里有三类居民

CodeChef April Challenge 2019题解

传送门 \(Maximum\ Remaining\) 对于两个数\(a,b\),如果\(a=b\)没贡献,所以不妨假设\(a<b\),有\(a\%b=a\),而\(b\%a<a\).综上,我们可以发现答案就是严格次大值 //minamoto #include<bits/stdc++.h> #define R register #define fp(i,a,b) for(R int i=(a),I=(b)+1;i<I;++i) #define fd(i,a,b) for(R i

CodeChef DISTNUM2 Easy Queries 节点数组线段树

Description You are given an array A consisting of N positive integers. You have to answer Q queries on it of following type: l r k : Let S denote the sorted (in increasing order) set of elements of array A with its indices between l and r. Note that

codechef Tree and Queries Solved

题目链接: https://www.codechef.com/problems/IITK1P10 大概是:修改点值,求子树节点为0有多少个, DFS序后,BIT 询问,修改 1 #include<bits/stdc++.h> 2  3 using namespace std; 4 typedef long long ll; 5  6 #define N 223456 7 ll val[N]; 8 int l[N],r[N]; 9 int t=1;10 int f[N];11 int lowbi

Maximum number, GCD condition (codechef March Challenge 2014)

题目 : http://acm.bnu.edu.cn/v3/problem_show.php?pid=40489 最近做到的一道蛮有意思的题目(codechef现在的题目确实很赞了) 题意 :中文题面 (cc的一大好处就是有中文翻译,嘿嘿) 区间Max = max{a_i|gcd(a_i, g) > 1 && x <= i <= y} 做法 : 一开始我是用分块做的,复杂的O(m * sqrt(n) * C) C 是所含不同素数的个数, C大概最大只有6或7吧 然后裸裸的

Codechef March Challenge 2014——The Street

The Street Problem Code: STREETTA https://www.codechef.com/problems/STREETTA Submit Tweet All submissions for this problem are available. Read problems statements in Mandarin Chineseand Russian. The String street is known as the busiest street in Cod

CF&amp;&amp;CC百套计划2 CodeChef December Challenge 2017 Chef And his Cake

https://www.codechef.com/DEC17/problems/GIT01 #include<cstdio> #include<algorithm> using namespace std; #define N 101 char s[N]; int main() { int T; scanf("%d",&T); int n,m; int OddG,OddR,EvenG,EvenR; int ans; while(T--) { OddG=O

CF&amp;&amp;CC百套计划2 CodeChef December Challenge 2017 Chef and Hamming Distance of arrays

https://www.codechef.com/DEC17/problems/CHEFHAM #include<cstdio> #include<cstring> #include<iostream> using namespace std; #define N 100001 int a[N],b[N]; int sum[N],wh[N][2]; int num1[N],num2[N]; void read(int &x) { x=0; char c=getc