zoukankan      html  css  js  c++  java
  • FZU 2059 MM (并查集+排序插入)

    Problem 2059 MM

    Accept: 109    Submit: 484
    Time Limit: 1000 mSec    Memory Limit : 32768 KB

     Problem Description

    There is a array contain N(1<N<=100000) numbers. Now give you M(1<M<10000) query.

    Every query will be:

    1 x : ask longest substring which every number no less than x

    2 y x : change the A[y] to x. there are at most change 10 times.

    For each ask can you tell me the length of longest substring.

     Input

    There are multiple tests.

    each test first line contain two integer numbers N M,second line contain N integer numbers.

    Next M lines each line will be:

    1 x : ask longest substring which every number no less than x

    2 y x : change the A[y] to x. there are at most change 10 times.

    0 < N <= 100000, 0 < M <= 10000, -1000000000 <= A[i] <= 1000000000

     Output

    Each ask output the length of longest substring .

     Sample Input

    5 5 1 2 3 2 1 1 2 1 3 2 3 1 1 2 1 3

     Sample Output

    3 1 1 0
     
    题意:  给一个数列,两种操作,第一种操作是输入一个x,查找一个子串满足每个元素的值都不小于x且长度最大,输出这个最大值,第二个操作是输入x和y,修改a[y]=x,第二个操作最多只有十次
     
    思路: o(nlogn)预处理,o(logn)查询。由于修改操作只有10次,所以每次修改都直接暴力预处理一遍,然后考虑没有修改操作的情况。
    预处理方法:把数列值排序一下,然后从大到小逐个插入,用并查集维护插入的这个点能连接的最长长度,在这个过程中维护一个最大值,最大值就是答案了。
     
    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    typedef long long ll;
    typedef pair<int,int> pii;
    const int INF = 1e9;
    const double eps = 1e-6;
    const int N = 100010;
    int cas = 1;
    
    struct _node{
        int pos,val,ans;
        friend bool operator < (const _node &a, const _node &b)
        {
            return a.val < b.val;
        }
    };
    int n,m;
    int fa[N],sum[N],b[N],mxval;
    _node a[N];
    
    int find(int x)
    {
        return fa[x]==x?x:fa[x]=find(fa[x]);
    }
    
    void un(int u,int v)
    {
        u=find(u), v=find(v);
        fa[u]=v;
        sum[v]+=sum[u];
    }
    
    void pre()
    {
        memset(sum,0,sizeof(sum));
        mxval = -INF-10;
        for(int i=0;i<n;i++) fa[i]=i;
        for(int i=0;i<n;i++)
        {
            a[i].val=b[i],a[i].pos=i;
            if(a[i].val > mxval) mxval = a[i].val;
        }
        sort(a,a+n);
        int mx = 0;
        for(int i=n-1;i>=0;i--)
        {
            sum[a[i].pos]=1;
            if(sum[a[i].pos-1]) un(a[i].pos-1,a[i].pos);
            if(sum[a[i].pos+1]) un(a[i].pos+1,a[i].pos);
            if(mx < sum[find(a[i].pos)]) mx = sum[fa[a[i].pos]];
            a[i].ans = mx;
        }
    }
    
    int solve(int x)
    {
        _node t;
        t.val=x;
        int id = lower_bound(a,a+n,t) - a;
        return a[id].ans;
    }
    
    void run()
    {
        for(int i=0;i<n;i++)
            scanf("%d",b+i);
        pre();
        int x,y,op;
        while(m--)
        {
            scanf("%d",&op);
            if(op==1)
            {
                scanf("%d",&x);
                if(x>mxval) puts("0");
                else printf("%d
    ",solve(x));
            }
            else
            {
                scanf("%d%d",&y,&x);
                b[y-1]=x;
                pre();
            }
        }
    }
    
    int main()
    {
        #ifdef LOCAL
        freopen("case.txt","r",stdin);
        #endif
        while(scanf("%d%d",&n,&m)!=EOF)
            run();
        return 0;
    }
  • 相关阅读:
    centos7之添加开机启动服务/脚本
    高性能 Windows C++ 通用组件 VCLogger v2.0.3 正式发布
    Kerberos认证流程
    使用Spring.Net+NHibernate构建WCF应用
    国家重点基础研究发展计划和重大科学研究计划方向
    项目实现思路(不断更新)
    LINQ新特性简介及入门教程
    XXX公司CRM项目开发日志
    GridView的增删改查和分页
    团队开发之环境搭建
  • 原文地址:https://www.cnblogs.com/someblue/p/4048256.html
Copyright © 2011-2022 走看看