SPOJ MULTQ3

/*sum[root][i]表示root节点的子叶子%3余i的总数 lazy懒惰标记*/

 1 #include <cstdio>
 2 #include <iostream>
 3 using namespace std;
 4 #define N 400010
 5 int sum[N][3],lazy[N];
 6 void pushup(int root){
 7     for(int i=0;i<3;i++){
 8         sum[root][i]=sum[root*2][i]+sum[root*2+1][i];
 9     }
10 }
11 void pushdown(int root){
12     int lr=root*2,rr=root*2+1,tem;
13     if(lazy[root] != 0) {
14         lazy[lr] =(lazy[lr]+lazy[root])%3;
15         lazy[rr]=(lazy[rr]+lazy[root])%3;
16         if(lazy[root]==1){
17             tem=sum[lr][1];
18             sum[lr][1]=sum[lr][0];
19             sum[lr][0]=sum[lr][2];
20             sum[lr][2]=tem;
21         }
22         else if(lazy[root]==2){
23             tem=sum[lr][1];
24             sum[lr][1]=sum[lr][2];
25             sum[lr][2]=sum[lr][0];
26             sum[lr][0]=tem;
27         }
28         if(lazy[root]==1){
29             tem=sum[rr][1];
30             sum[rr][1]=sum[rr][0];
31             sum[rr][0]=sum[rr][2];
32             sum[rr][2]=tem;
33         }
34         else if(lazy[root]==2){
35             tem=sum[rr][1];
36             sum[rr][1]=sum[rr][2];
37             sum[rr][2]=sum[rr][0];
38             sum[rr][0]=tem;
39         }
40         lazy[root]=0;
41     }
42 }
43 void build(int l,int r,int root){
44     lazy[root]=0,sum[root][0]=1,sum[root][1]=0,sum[root][2]=0;
45     if(l==r)return ;
46     int mid=(l+r)/2;
47     build(l,mid,root*2);
48     build(mid+1,r,root*2+1);
49     pushup(root);
50 }
51 void update(int x,int y,int l,int r,int root){
52     int mid=(r+l)/2,tem;
53     if(x<=l&&y>=r){
54         lazy[root]=(1+lazy[root])%3;
55         tem=sum[root][1];
56         sum[root][1]=sum[root][0];
57         sum[root][0]=sum[root][2];
58         sum[root][2]=tem;
59         return ;
60     }
61     pushdown(root);
62     if(x<=mid)update(x,y,l,mid,root*2);
63     if(y>mid)update(x,y,mid+1,r,root*2+1);
64     pushup(root);
65 }
66 int query(int x,int y,int l,int r,int root){
67     if(x<=l&&y>=r){
68         return sum[root][0];
69     }
70     pushdown(root);
71     int mid=(r+l)/2,ans=0;
72     if(x<=mid)ans+=query(x,y,l,mid,root*2);
73     if(y>mid)ans+=query(x,y,mid+1,r,root*2+1);
74     return ans;
75 }
76 int main(){
77     //freopen("test.txt","r",stdin);
78     int n,q,x,y,z;
79         scanf("%d%d",&n,&q);
80         build(0,n,1);
81         for(int i=0;i<q;i++){
82             scanf("%d%d%d",&z,&x,&y);
83             if(z==1)printf("%d\n",query(x,y,0,n,1));
84             else update(x,y,0,n,1);
85         }
86     return 0;
87 }

SPOJ MULTQ3

时间: 2025-01-11 04:06:17

SPOJ MULTQ3的相关文章

暑期测试训练3

1.Codeforces 20C spfa算法的简单题,在这个过程中多了一个记录连接最短路径上的前一个节点的位置的数组,然后将这个数组逆向输出 在这道题目中,我路径数组范围居然忘记*2了,结果一直报错,找了好久,%>_<% #include <iostream> #include <cstdio> #include <queue> #include <cstring> using namespace std; #define N 100010 #

CSU-ACM暑假集训基础组七夕专场

•Problem A Codeforces 20C       最短路(dij,spfa) •题意:给出一张n个点m条边的无向图 (2 ≤ n ≤ 105, 0 ≤ m ≤ 105),输出从1到n的任意一条最短路径. •解法:dijkstra或者spfa,用pre数组记录到达每个点最短距离的前驱结点. •注意:路径的长度范围是 1 ≤ wi ≤ 106,从1到n的最短路径长度可能超出int范围. •没有路径从1到达n时要输出-1 1 #include <cstdio> 2 #include &

SPOJ 705 Distinct Substrings(后缀数组)

[题目链接] http://www.spoj.com/problems/SUBST1/ [题目大意] 给出一个串,求出不相同的子串的个数. [题解] 对原串做一遍后缀数组,按照后缀的名次进行遍历, 每个后缀对答案的贡献为n-sa[i]+1-h[i], 因为排名相邻的后缀一定是公共前缀最长的, 那么就可以有效地通过LCP去除重复计算的子串. [代码] #include <cstdio> #include <cstring> #include <algorithm> usi

SPOJ 3273

传送门: 这是一道treap的模板题,不要问我为什么一直在写模板题 依旧只放代码 1 //SPOJ 3273 2 //by Cydiater 3 //2016.8.31 4 #include <iostream> 5 #include <cstring> 6 #include <ctime> 7 #include <cmath> 8 #include <cstdlib> 9 #include <string> 10 #include

SPOJ CRAN02 - Roommate Agreement

题目链接:http://www.spoj.com/problems/CRAN02/ 题目大意:N个数字组成的序列,和为0的连续子序列的个数.N<1e6 解题思路:计算前缀和,统计每个数字出现的次数,那么对于数字sum[i], 如果存在k个sum[i],则代表有C(k, 2)个序列和为0,而如果sum[i] = 0,则还要累加上对应的k值. 代码: 1 ll n; 2 int a[maxn]; 3 ll sum[maxn]; 4 map<int, int> mmp; 5 6 void so

spoj GCJ1C09C Bribe the Prisoners

题目链接: http://www.spoj.com/problems/GCJ1C09C/ 题意: In a kingdom there are prison cells (numbered 1 to P) built to form a straight line segment. Cells number i and i+1 are adjacent, and prisoners in adjacent cells are called "neighbours." A wall wi

SPOJ QTREE Query on a tree ——树链剖分 线段树

[题目分析] 垃圾vjudge又挂了. 树链剖分裸题. 垃圾spoj,交了好几次,基本没改动却过了. [代码](自带常数,是别人的2倍左右) #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> using namespace std; #define maxn 20005 int T,n,fr[maxn],h[maxn],to[maxn],ne[maxn]

BZOJ 2588: Spoj 10628. Count on a tree 主席树+lca

2588: Spoj 10628. Count on a tree Description 给定一棵N个节点的树,每个点有一个权值,对于M个询问(u,v,k),你需要回答u xor lastans和v这两个节点间第K小的点权.其中lastans是上一个询问的答案,初始为0,即第一个询问的u是明文. Input 第一行两个整数N,M. 第二行有N个整数,其中第i个整数表示点i的权值. 后面N-1行每行两个整数(x,y),表示点x到点y有一条边. 最后M行每行两个整数(u,v,k),表示一组询问.

BZOJ 1002 + SPOJ 104 基尔霍夫矩阵 + 一个递推式。

BZOJ 1002 高精度 + 递推 f[1] = 1; f[2] = 5; f[i] = f[i - 1] * 3 - f[i - 2] + 2; SPOJ 104 裸 + 不用Mod 1 #include <cstdio> 2 #include <cstring> 3 #include <cstdlib> 4 #include <algorithm> 5 #include <iostream> 6 7 using namespace std;