• 【BZOJ】3211: 花神游历各国


    题意

    (n)个点,第(i)个点值为(a_i)(m)个询问,每次询问([l, r])内的和或者将([l, r])的每个值改为自己的算术平方根。((n le 100000, m le 200000, 0 le a_i le 10^9)

    分析

    (10^9)开几次方就到(1)或者(0)了,所以对于已经到(1)(0)的我们可以直接跳过。

    题解

    我们用一个并查集来维护"下一个"。即(p_i)表示从当前点开始不为(1)(0)的数的下一个位置(包括自己)。用并查集合并即可。

    #include <bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const int N=100005;
    int n, a[N], p[N];
    ll c[N];
    inline void add(int x, int s) {
    	for(; x<=n; x+=x&-x) {
    		c[x]+=s;
    	}
    }
    inline ll sum(int x) {
    	ll y=0;
    	for(; x; x-=x&-x) {
    		y+=c[x];
    	}
    	return y;
    }
    inline int find(int x) {
    	return x==p[x]?x:p[x]=find(p[x]);
    }
    inline int getint() {
    	char c=getchar();
    	int x=0;
    	for(; c<'0'||c>'9'; c=getchar());
    	for(; c>='0'&&c<='9'; c=getchar()) {
    		x=x*10+c-48;
    	}
    	return x;
    }
    int main() {
    	n=getint();
    	for(int i=1; i<=n; ++i) {
    		a[i]=getint();
    		add(i, a[i]);
    		p[i]=i;
    	}
    	p[n+1]=n+1;
    	int m=getint();
    	while(m--) {
    		int x, l, r;
    		x=getint();
    		l=getint();
    		r=getint();
    		if(x==1) {
    			printf("%lld
    ", sum(r)-sum(l-1));
    		}
    		else {
    			for(int i=find(l); i<=r; i=find(i+1)) {
    				add(i, -a[i]);
    				a[i]=sqrt(a[i]);
    				add(i, a[i]);
    				if(a[i]<=1) {
    					p[i]=find(p[i+1]);
    				}
    			}
    		}
    	}
    	return 0;
    }
  • 相关阅读:
    1058 A+B in Hogwarts (20)
    1046 Shortest Distance (20)
    1061 Dating (20)
    1041 Be Unique (20)
    1015 Reversible Primes (20)(20 分)
    pat 1027 Colors in Mars (20)
    PAT 1008 Elevator (20)
    操作系统 死锁
    Ajax的get方式传值 避免& 与= 号
    让IE浏览器支持CSS3表现
  • 原文地址:https://www.cnblogs.com/iwtwiioi/p/4985810.html
Copyright © 2020-2023  润新知