wust1593线段树
来源:互联网 发布:pes2017曼城数据 编辑:程序博客网 时间:2024/05/22 00:44
题目大意:给你n个数,m次操作,操作有两种 0 l r ,计算n个数从l乘到r后置0的个数,1 a b ,将a位置换位b。每个数均小于100,n,m< 100000.
思路:简单的线段树,每个节点维护该区间拥有的2的因子个数,5的因子个数,以及数据里是否拥有0.
每次计算,如果有0输出1,否则输出因子2和5的最小个数。
ps:记录0的个数的时候没有0忘记初始化为0.。。。。。。。
#include <iostream>#include <cstdio>#include <string>#include <cstring>#include <fstream>#include <algorithm>#include <cmath>#include <queue>#include <stack>#include <vector>#include <map>#include <set>#include <iomanip>using namespace std;#pragma comment(linker, "/STACK:102400000,102400000")#define maxn 200005#define MOD 1000000007#define mem(a , b) memset(a , b , sizeof(a))#define LL long long#define ULL long longconst long long INF=0x3fffffff;int arr[maxn];int n , m;int num_tree;struct tree{ int left , right ; int num2 , num5 , num0;}ST[3*maxn];int get2(int n){ int ans = 0; while(n % 2 == 0 && n) { n /= 2; ans ++; } return ans;}int get5(int n){ int ans = 0; while(n % 5 == 0 && n) { n /= 5; ans ++; } return ans;}void Build(int root , int left , int right){ ST[root].left = left; ST[root].right = right; if(left == right) { ST[root].num2 = get2(arr[left]); ST[root].num5 = get5(arr[left]); if(arr[left] == 0) ST[root].num0 = 1; else ST[root].num0 = 0; return ; } int mid = (left + right) / 2; Build(2 * root , left , mid); Build(2 * root + 1 , mid + 1 , right); ST[root].num0 = ST[root*2].num0 + ST[2*root + 1].num0; ST[root].num2 = ST[root*2].num2 + ST[2*root + 1].num2; ST[root].num5 = ST[root*2].num5 + ST[2*root + 1].num5;}void update(int root ,int pos , int val){ if(pos < ST[root].left || pos > ST[root].right) return ; int mid = (ST[root].right + ST[root].left) / 2; if(pos == ST[root].left && pos == ST[root].right) { ST[root].num2 = get2( val ); ST[root].num5 = get5( val ); if(val == 0) ST[root].num0 = 1; else ST[root].num0 = 0; return ; } if(pos <= mid) update(2*root , pos , val); else update(2 * root + 1 , pos ,val); ST[root].num0 = ST[root*2].num0 + ST[2*root + 1].num0; ST[root].num2 = ST[root*2].num2 + ST[2*root + 1].num2; ST[root].num5 = ST[root*2].num5 + ST[2*root + 1].num5;}int Query(int l , int r , int pos , int flag){ if(ST[pos].left > r || ST[pos].right < l) { return 0 ; } int temp = (ST[pos].right + ST[pos].left) / 2; if(ST[pos].left == l && ST[pos].right == r) { if(flag == 0) return ST[pos].num0; else if(flag == 2) return ST[pos].num2; else return ST[pos].num5; } else if(r <= temp) return Query(l , r , 2 * pos , flag); else if(l > temp) return Query(l , r , 2 * pos + 1 , flag); else if(l <= temp && r > temp) return Query(l , temp , 2 * pos , flag) + Query(temp + 1, r , 2 * pos + 1 , flag);}int main(){ while(scanf("%d %d" , &n , &m) != EOF) { for(int i = 1 ; i <= n ; i++) { scanf("%d" , &arr[i]); } if(n == 0 ) continue; Build(1 , 1 , n); int a , b , c; for(int i = 0 ; i < m ; i ++ ) { scanf("%d %d %d" , &a , &b , &c); if(a) { update(1 , b , c); } else { if(b > c) swap(b , c); if(Query(b , c , 1 , 0)) printf("1\n"); else printf("%d\n" , min(Query(b , c , 1 , 2 ) , Query(b , c , 1 , 5) ) ); } } } return 0;}
0 0
- wust1593线段树
- 线段树?线段树!
- 线段树?线段树!
- 线段_线段树
- 线段_线段树
- 线段树
- 线段树
- 线段树
- 线段树
- 线段树
- 线段树
- 线段树
- 线段树
- 线段树
- 线段树
- 线段树
- 线段树
- 线段树
- Docker 网络部分执行流分析(libnetwork源码解读)
- gimp 颜色替换
- Android关于OnTouch 和OnClick同时调用冲突的解决方案
- iOS - Cell高度不固定的情况处理
- Apache Maven的插件概述
- wust1593线段树
- 设计模式(Design Patterns)
- 编译原理--C-Minus词法分析器C++实现
- 使用cocoaPods 做依赖的管理
- YK线上机器redis配置(没有主从,单点,一致性哈希)
- DbUtils组件
- spring的事务解读
- 如何分析thread dump(另一篇)
- 天天学C#--数据访问类(一)