• BZOJ 4320


    (bzoj4320~~Homework)

    (1:)在人物集合 S 中加入一个新的程序员,其代号为(X),保证(X)在当前集合中不存在。

    (2:)在当前的人物集合中询问程序员的(mod~Y) 最小的值。 (为什么统计这个?因为拯救

    过世界的人太多了,只能取模)

    其中 对于 100%的数据:(N≤100000, 1≤X,Y≤300000,)保证第二行为操作 1。

    好神的题:根号分治+并查集

    (N)表示(x)的最大值,考虑对权值序列分治,当模数不超(sqrt N),开(sqrt N)个桶,每次暴力更新桶,(O(1))求答案

    当模数超过(sqrt N)时,它在(n)之内的倍数不超过(sqrt N)个, ,我们离线处理。把加点改成删点。 每次询问相当于询问当前数集中比Y或Y的倍数大并且距离最近的数。删点很显然可以用并查集处理,把空格都连起来(同花神游历各国)。

    #include<bits/stdc++.h>
    using namespace std;
    int n,siz,m,q[100010],f[300001];
    int ans[100010],st[610];
    bool vis[300010]; char str[10];
    int find(int x){return f[x] == x ? x : f[x] = find(f[x]);}
    int main(){
    	scanf("%d",&n); siz = 550;
    	int i,j; memset(st,0x3f,sizeof(st));
    	for(i = 1;i <= n;++i){
    		scanf("%s%d",str,&q[i]);
    		if(str[0] == 'A'){
    			for(int j = 1;j <= siz;++j) st[j] = min(st[j],q[i] % j);
    			m = max(m,q[i]),vis[q[i]] = 1,q[i] = -q[i];
    		}
    		else    if(q[i] <= siz) ans[i] = st[q[i]];
    	}
    	for(i = 0;i <= m+1;++i) f[i] = (vis[i]) ? i : i+1;
    	for(i = n;i >= 1;--i){
    		if(q[i] < 0) f[-q[i]] = find(-q[i]+1);
    		else{
    			if(q[i]>siz){
                    ans[i]=1 << 30;
                    for(j = 0;j <= m;j += q[i])    ans[i]=min(ans[i],find(j)%q[i]);
                }
    		}
    	}
    	 for(i=1;i<=n;i++)    if(q[i]>0)   printf("%d
    ",ans[i]);
    }
    
  • 相关阅读:
    Today
    react-decorator-track 解耦-埋点方案
    Decorator
    webpack4强势来袭
    同源策略与跨域处理
    html语义化
    深度遍历与广度遍历的理解
    Javascript 模块化理解
    算法之排序
    数组去重
  • 原文地址:https://www.cnblogs.com/shikeyu/p/13563525.html
Copyright © 2020-2023  润新知