zoukankan      html  css  js  c++  java
  • 2019 ICPC Asia Yinchuan Regional G. Pot!!(线段树/数论)

    Little Q is very sleepy, and he really needs some coffee to make him awake. At this time, Little L brings a pot to Little Q, and he states the pot as follows.

    For a prime number pp, if p^m | np**mn and p^{m+1} ot | np**m+1∣n, we say ext{pot}_p(n)=mpotp(n)=m.

    The pot is very special that it can make everyone awake immediately.

    Now Little L provides n~(1 le n le 10^5)n (1≤n≤105) integers a_1, a_2, cdots, a_na1,a2,⋯,a**n to Little Q, each of which is 11 initially. After that, Little L shows 22 types of queries:

    • MULTIPLY l r x : For every i in [l,r]i∈[l,r] (1le lle rle n1≤lrn), multiply a_ia**i by xx (2 le x le 102≤x≤10).

    • MAX l r : Calculate the value of

      displaystyle max_{lle ile r} left{ max_{p|a_i} left{ ext{pot}_p (a_i) ight} ight}~(1 le l le r le n),lirmax{pa**imax{potp(a**i)}} (1≤lrn),

    where pp is prime.

    Now you need to perform q~(1 le q le 10^5)q (1≤q≤105) queries of these two types of queries described above.

    If you perform a “MULTIPLY” query, you don't need to output anything.

    If you perform a “MAX” query, you need to output a line like ANSWER y, where yy the value you've calculated.

    Input

    The first line contains two integers n~(1 le n le 10^5)n (1≤n≤105) and q~(1 le q le 10^5)q (1≤q≤105), the number of integers and the number of queries.

    Each of the next qq lines contains one type of query described above.

    Output

    For each “MAX” query, output one line in the format of ANSWER y, where yy the value you have calculated.

    样例输入复制

    5 6
    MULTIPLY 3 5 2
    MULTIPLY 2 5 3
    MAX 1 5
    MULTIPLY 1 4 2 
    MULTIPLY 2 5 5 
    MAX 3 5
    

    样例输出复制

    ANSWER 1
    ANSWER 2
    

    样例解释

    If mm and nn are non-zero integers, or more generally, non-zero elements of an integral domain, it is said that mm divides nn if there exists an integer kk, or an element kk of the integral domain, such that m imes k=nm×k=n, and this is written as m mid nmn.

    编辑代码

    题面直接复制过来有点拉。

    每次把乘数分解质因子 因为乘数在1到10 因此最后对每个数分解质因数只有四个质数 可以开四棵线段树 分别统计a[i]的这个质因子个数 维护区间最大值。最后对四棵线段树的查询结果取max即可。别忘记懒标记。

    #include <bits/stdc++.h>
    #define int long long
    #define N 100005
    using namespace std;
    int n, q;
    int a[100005];
    struct SegmentTree {
    	int p, l, r;
    	int add, dat;
    } t[4][N * 4 + 5];
    void build(int id, int p, int l, int r) {
    	t[id][p].l = l, t[id][p].r = r, t[id][p].add = 0;
    	if(t[id][p].l == t[id][p].r) {
    		t[id][p].dat = 0;
    		return;
    	}
    	int mid = (l + r) >> 1;
    	build(id, 2 * p, l, mid);
    	build(id, 2 * p + 1, mid + 1, r);
    	t[id][p].dat = max(t[id][2 * p].dat, t[id][2 * p + 1].dat);
    }
    void spread(int id, int p) {
    	if(t[id][p].add) {
    		t[id][2 * p].dat += t[id][p].add;
    		t[id][2 * p + 1].dat += t[id][p].add;
    		t[id][2 * p].add += t[id][p].add;
    		t[id][2 * p + 1].add += t[id][p].add;
    		t[id][p].add = 0;
    	}
    }
    void change(int id, int p, int l, int r, int x) {
    	if(t[id][p].l >= l && t[id][p].r <= r) {
    		t[id][p].dat += x;
    		t[id][p].add += x;
    		return;
    	}
    	spread(id, p);
    	int mid = (t[id][p].l + t[id][p].r) >> 1;
    	if(l <= mid) {
    		change(id, 2 * p, l, r, x);
     	}
    	if(r > mid) {
    		change(id, 2 * p + 1, l, r, x);
    	}
    	t[id][p].dat = max(t[id][2 * p].dat, t[id][2 * p + 1].dat);
    }
    int ask(int id, int p, int l, int r) {
    	if(t[id][p].l >= l && t[id][p].r <= r) {
    		return t[id][p].dat;
    	}
    	spread(id, p);
    	int mid = (t[id][p].l + t[id][p].r) >> 1;
    	int ans = -0x3f3f3f3f;
    	if(l <= mid) {
    		ans = max(ans, ask(id, 2 * p, l, r));
    	}
    	if(r > mid) {
    		ans = max(ans, ask(id, 2 * p + 1, l, r));
    	}
    	return ans;
    }
    //每次把乘数分解质因子 因为乘数在1到10 因此只有四个质数 可以开四棵线段树 分别统计a[i]的这个质因子个数 维护区间最值 
    //最后对四棵线段树的查询结果取max即可。
    signed main() {
    	//freopen("data.txt", "r", stdin);
    	cin >> n >> q;
    	for(int i = 1; i <= n; i++) a[i] = 0;
    	build(0, 1, 1, n);
    	build(1, 1, 1, n);
    	build(2, 1, 1, n);
    	build(3, 1, 1, n);
    	for(int i = 1; i <= q; i++) {
    		string s;
    		cin >> s;
    		if(s == "MULTIPLY") {
    			int l, r, x;
    			cin >> l >> r >> x;
    			int p[4], cnt[4];
    			for(int i = 0; i < 4; i++) cnt[i] = 0;
    			p[0] = 2, p[1] = 3, p[2] = 5, p[3] = 7;
    			for(int i = 0; i < 4; i++) {
    				while(x % p[i] == 0) {
    					++cnt[i];
    					x /= p[i];
    				}
    				change(i, 1, l, r, cnt[i]);
    			}
    		} else {
    			int l, r;
    			cin >> l >> r;
    			int ans = -0x3f3f3f3f;
    			for(int i = 0; i < 4; i++) {
    				ans = max(ans, ask(i, 1, l, r));
    			}
    			cout << "ANSWER " << ans << endl;
    		}
    	}
    	return 0;
    }
    
  • 相关阅读:
    关于javaScript substring()方法的一点点应用
    解决Vue报错:Invalid prop: type check failed for prop "id". Expected Number with value 14, got String with value "14".
    better-scroll滚动无效的查错
    Vue程序化导航---又称编程式导航
    Vue路由初始化Can't read prooerty '$createElement' of undefined
    在前台利用jquery对dom元素进行排序
    js/jquery如何获取获取父窗口的父窗口的元素
    jquery使鼠标滚轮暂时失效
    introJs写法
    用Intro.js创建站点分步指南
  • 原文地址:https://www.cnblogs.com/lipoicyclic/p/14746433.html
Copyright © 2011-2022 走看看