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;
    }
    
  • 相关阅读:
    day08
    day07
    day06
    day06
    day05
    第三次作业
    第三次作业
    第二次作业
    java 数字和日期处理
    jsp文件导包
  • 原文地址:https://www.cnblogs.com/lipoicyclic/p/14746433.html
Copyright © 2011-2022 走看看