Codeforces Round #406 (Div. 2) E. Till I Collapse(主席树)

题目链接:Codeforces Round #406 (Div. 2) E. Till I Collapse

题意:

给你n个数,对于每一个k(1<=k<=n),划分区间,每个区间只能有k个不同的数字,

问最小的划分区间的个数。

题解:

用主席树倒着将数插入,对于每个区间询问第k个不同数的位置就行了。

#include<bits/stdc++.h>
#define F(i,a,b) for(int i=a;i<=b;i++)
#define ___ freopen("in.txt","r",stdin);
using namespace std;
typedef long long ll;

const int N=1e5+7;

int root[N],a[N],cnt,pre[N],n;

struct node{int l,r,sum;}T[N*40];

void update(int l,int r,int &x,int y,int pos,int val)
{
    T[++cnt]=T[y],T[x=cnt].sum+=val;
    if(l==r)return;
    int mid=l+r>>1;
    if(mid>=pos)update(l,mid,T[x].l,T[y].l,pos,val);
    else update(mid+1,r,T[x].r,T[y].r,pos,val);
}

int query(int l,int r,int x,int k)
{
    if(l==r)return l;
    int mid=l+r>>1;
    if(k<=T[T[x].l].sum)return query(l,mid,T[x].l,k);
    else return query(mid+1,r,T[x].r,k-T[T[x].l].sum);
}

int main()
{
    scanf("%d",&n);
    F(i,1,n)scanf("%d",a+i);
    for(int i=n;i>0;i--)
    {
        update(1,n,root[i],root[i+1],i,1);
        if(pre[a[i]])update(1,n,root[i],root[i],pre[a[i]],-1);
        pre[a[i]]=i;
    }
    F(i,1,n)
    {
        int now=1,ans=0;
        while(now<=n)
        {
            if(T[root[now]].sum>i)now=query(1,n,root[now],i+1);
            else now=n+1;
            ans++;
        }
        printf("%d%c",ans," \n"[i==n]);
    }
    return 0;
}

时间: 2024-11-07 19:01:26

Codeforces Round #406 (Div. 2) E. Till I Collapse(主席树)的相关文章

Codeforces Round #406 (Div. 2)

A - The Monster(暴力)[AC:3k+] 题意: 给定整数a,b,c,d(1<=a,b,c,d<=100),求是否有y满足  y=a*x1+b=c*x2+d.x1,x2为正整数. 思路: 我们考虑成两条直线在坐标系上,然后你想极端情况,两者相交使得y最大,是不是a=c=100的时候,在无穷远处相交(平行嘛),那么c小一点点y=99x+100,y=100x+0.所以可以发现y的范围肯定不会超过10000.所以暴力出10000的范围内的数据,匹配一下有无答案就行了. 1 #inclu

Codeforces 464E #265 (Div. 1) E. The Classic Problem 主席树+Hash

E. The Classic Problem http://codeforces.com/problemset/problem/464/E 题意:给你一张无向带权图,求S-T的最短路,并输出路径.边权为2^xi.xi≤105,n≤105,m≤105. 想法:边权太大了,可以用数组按二进制存下来.带高精度跑太费事了. 观察一下,这里距离的更新:c=(a,b),用dis[a]更新dis[b] ①dis[b][c]=0,直接赋为1.只有一个数字改变. ②dis[b][c]=1,需要进位.考虑极端情况数

区间-&gt;点,点-&gt;区间,线段树优化建图+dijstra Codeforces Round #406 (Div. 2) D

http://codeforces.com/contest/787/problem/D 题目大意:有n个点,三种有向边,这三种有向边一共加在一起有m个,然后起点是s,问,从s到所有点的最短路是多少? 第一种边:u->v w 表示节点u到v有连接一条有向边,权值为w 第二种边:u->[l,r] w  表示节点u到区间[l,r]连接一条有向边,权值为w 第三种边:[l,r]->u w  表示区间[l, r]所有的节点到u都有一条有向边,权值为w 思路: 我们知道,对于dijstra都是用pr

【动态规划】Codeforces Round #406 (Div. 2) C.Berzerk

有向图博弈问题. 能转移到一个必败态的就是必胜态. 能转移到的全是必胜态的就是必败态. 转移的时候可以用队列维护. 可以看这个 http://www.cnblogs.com/quintessence/p/6618640.html #include<cstdio> #include<queue> using namespace std; struct Node{ int who,pos; }; queue<Node>q; int n,len[2],to[2][7010],

Codeforces Round #149 (Div. 2) E. XOR on Segment (线段树成段更新+二进制)

题目链接:http://codeforces.com/problemset/problem/242/E 给你n个数,m个操作,操作1是查询l到r之间的和,操作2是将l到r之间的每个数xor与x. 这题是线段树成段更新,但是不能直接更新,不然只能一个数一个数更新.这样只能把每个数存到一个数组中,长度大概是20吧,然后模拟二进制的位操作.仔细一点就行了. 1 #include <iostream> 2 #include <cstdio> 3 #include <cmath>

Codeforces Round #225 (Div. 1) C. Propagating tree dfs序+树状数组

C. Propagating tree Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/contest/383/problem/C Description Iahub likes trees very much. Recently he discovered an interesting tree named propagating tree. The tree consists of n nodes numb

Codeforces Round #365 (Div. 2) D. Mishka and Interesting sum 树状数组

D. Mishka and Interesting sum 链接: http://codeforces.com/problemset/problem/703/D 题意: 给一个序列 每次询问一个区间 求区间中出现次数为偶数次的数的异或和 代码: 1 #include<iostream> 2 #include<cstdio> 3 #include<algorithm> 4 #include<map> 5 using namespace std; 6 7 str

Codeforces Round #207 (Div. 1) A. Knight Tournament (线段树离线)

题目:http://codeforces.com/problemset/problem/356/A 题意:首先给你n,m,代表有n个人还有m次描述,下面m行,每行l,r,x,代表l到r这个区间都被x所击败了(l<=x<=r),被击败的人立马退出游戏让你最后输出每个人是被谁击败的,最后那个胜利者没被 人击败就输出0 思路:他的每次修改的是一个区间的被击败的人,他而且只会记录第一次那个被击败的人,用线段树堕落标记的话他会记录最后一次的,所以我们倒着来修改, 然后因为那个区间里面还包含了自己,在线段

Codeforces Round #590 (Div. 3) D. Distinct Characters Queries(线段树, 位运算)

链接: https://codeforces.com/contest/1234/problem/D 题意: You are given a string s consisting of lowercase Latin letters and q queries for this string. Recall that the substring s[l;r] of the string s is the string slsl+1-sr. For example, the substrings