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\n",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;
}
时间: 2024-10-29 04:28:50

FZU 2059 MM (并查集+排序插入)的相关文章

程序自动分析(并查集+排序)

题意 给许多个x,y,k,若k=1,x==y,否则x!=y,如果矛盾,输出NO,否则YES 对于k=1,并查集简单操作一下,k=0,如果find(x)==find(y),打个标记,输出NO: 有一个需要注意的地方是,对于询问我们要进行sort,使k=1的情况先执行,这样可以保证最后判断的答案正确. #include<iostream> #include<cstdio> using namespace std; int re(){ char c=getchar();int all=0

FZU 2059 MM

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. F

【FZU】Problem 2059 MM(离线处理并查集)

离线处理,并查集 #include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int maxn = 100005; struct Node{ int id,value; }node[maxn],input[maxn]; bool cmp(Node p,Node q){ return p.value > q.value; } int p[maxn],vis[max

fzu 2059 并查集+离线处理

题意: 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

HDU 1811 Rank of Tetris(并查集按秩合并+拓扑排序)

Rank of Tetris Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 9267    Accepted Submission(s): 2668 Problem Description 自从Lele开发了Rating系统,他的Tetris事业更是如虎添翼,不久他遍把这个游戏推向了全球. 为了更好的符合那些爱好者的喜好,Lele又想

FZU 2112 并查集、欧拉通路

原题:http://acm.fzu.edu.cn/problem.php?pid=2112 首先是,票上没有提到的点是不需要去的. 然后我们先考虑这个图有几个联通分量,我们可以用一个并查集来维护,假设有n个联通分量,我们就需要n-1条边把他们连起来. 最后对于每个联通分量来说,我们要使它能一次走完,就是要求他是否满足欧拉通路,也就是这个联通分量中至多有2个度为奇数的点,每多出2个度为奇数的点,就多需要一条边(因为单个连通分量的所有点的度数之和为偶数,所以不可能存在奇数个奇数度数的点). 1 #i

hdu 1811 Rank of Tetris(拓扑排序+并查集)

1 #include "cstdio" 2 #include "iostream" 3 #include "cstring" 4 #include "vector" 5 #include "queue" 6 using namespace std; 7 const int N = 10005; 8 int n, m, t; 9 int fa[N]; 10 int rank[N]; 11 int X[2*N]

HDU 1811:Rank of Tetris(并查集+拓扑排序)

http://acm.hdu.edu.cn/showproblem.php?pid=1811 Rank of Tetris Problem Description 自从Lele开发了Rating系统,他的Tetris事业更是如虎添翼,不久他遍把这个游戏推向了全球.为了更好的符合那些爱好者的喜好,Lele又想了一个新点子:他将制作一个全球Tetris高手排行榜,定时更新,名堂要比福布斯富豪榜还响.关于如何排名,这个不用说都知道是根据Rating从高到低来排,如果两个人具有相同的Rating,那就按

POJ 3660Cow Contest(并查集+拓扑排序)

Cow Contest Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 7567   Accepted: 4206 Description N (1 ≤ N ≤ 100) cows, conveniently numbered 1..N, are participating in a programming contest. As we all know, some cows code better than others