POJ - 2886线段树+线性筛

题意就是给你n个人,每个人有一个名字和A,如果A为正则向左找第A个,否则向右找第-A个,每找到一个就出列,然后第i个人出列的F(i)是i的所有因子个数

输出最大的F(i)和对应的名字

先用线性筛找出第几个出列的值最大maxn,那么求到maxn就可以了。

用线段树记录空位,k表示当前需要从剩余人第几个位置寻找,只要推出k,则转化为线段树的求位置的模型

#include<iostream>
#include<cstdio>
#include<cstring>

using namespace std;
const int N=500010;
char name[N][15];
int pos[N];
int cnt[N];
struct node
{
    int l,r;
    int spare;
} seg[N<<2];

void pushup(int rt)
{
    seg[rt].spare=seg[2*rt].spare+seg[2*rt+1].spare;
}
void build(int rt,int L,int R)
{
    seg[rt].l=L;
    seg[rt].r=R;
    seg[rt].spare=1;
    if(L==R)
    {
        return;
    }
    int mid=(seg[rt].l+seg[rt].r)/2;
    build(2*rt,L,mid);
    build(2*rt+1,mid+1,R);
    pushup(rt);
}

int index;
void update(int rt,int val)
{
    if(seg[rt].l==seg[rt].r)
    {
        index = seg[rt].l;
        seg[rt].spare=0;
        return;
    }
    if(seg[2*rt].spare>=val)
        update(2*rt,val);
    else
        update(2*rt+1,val-seg[2*rt].spare);
    pushup(rt);
}
int slove(int n)//线性筛求最大
{
    int maxcnt=-0x3f3f3f3f;
    int maxn;
    memset(cnt,0,sizeof(cnt));
    for (int i=1; i<=n ; i++ )
    {
        cnt[i]++;
        for (int j=2*i; j<=n ; j+=i )
            cnt[j]++;
    }
    for (int i=1; i<=n ; i++ )
    {
        if(cnt[i]>maxcnt)
        {
            maxcnt=cnt[i];
            maxn=i;
        }
    }
    return maxn;
}
int main()
{
    int n,k;
    while(~scanf("%d%d",&n,&k))
    {
        int maxn=slove(n);
        for (int i=1; i<=n ; i++ )
        {
            scanf("%s %d",name[i],&pos[i]);
        }
        build(1,1,n);
        int mod=seg[1].spare;
        pos[0]=0;
        index=0;
        for (int i=1; i<=maxn; i++ )
        {
            if(pos[index]>0)
            {
                k=(k-1+pos[index]-1)%mod+1;
            }
            else
            {
                k=((k+pos[index]-1+mod)%mod+mod)%mod+1;
            }
            update(1,k);
            mod=seg[1].spare;
        }
        printf("%s %d\n",name[index],cnt[maxn]);
    }
    return 0;
}

原文地址:https://www.cnblogs.com/Json-Five/p/9825413.html

时间: 2024-08-30 12:03:04

POJ - 2886线段树+线性筛的相关文章

poj 2886 线段树的更新+反素数

Who Gets the Most Candies? Time Limit: 5000 MS Memory Limit: 0 KB 64-bit integer IO format: %I64d , %I64u Java class name: Main [Submit] [Status] [Discuss] Description N children are sitting in a circle to play a game. The children are numbered from

poj 2886 (线段树+反素数打表) Who Gets the Most Candies?

http://poj.org/problem?id=2886 一群孩子从编号1到n按顺时针的方向围成一个圆,每个孩子手中卡片上有一个数字,首先是编号为k的孩子出去,如果他手上的数字m是正数,那么从他左边(顺时针)开始第m个孩子出去,如果是负的 那么从他的右边(也就是逆时针)开始第m个孩子出去~~~一直到所有的孩子出去,另外,第p个出去的孩子可以得到的糖果数量是p的约数个数,问能得到最多糖果的孩子的名字和得到的糖果数目 关于公约数最多的问题,可以利用到反素数,可以首先先打表反素数和对应的约数个数,

【Educational Codeforces Round 37】F. SUM and REPLACE 线段树+线性筛

题意 给定序列$a_n$,每次将$[L,R]$区间内的数$a_i$替换为$d(a_i)$,或者询问区间和 这题和区间开方有相同的操作 对于$a_i \in (1,10^6)$,$10$次$d(a_i)$以内肯定可以最终化为$1$或者$2$,所以线段树记录区间最大值和区间和,$Max\le2$就返回,单点暴力更新,最后线性筛预处理出$d$ 时间复杂度$O(m\log n)$ 代码 #include <bits/stdc++.h> using namespace std; typedef long

POJ 2886 线段树单点更新

转载自:http://blog.csdn.net/sdj222555/article/details/6878651 反素数拓展参照:http://blog.csdn.net/ACdreamers/article/details/25049767 题目大意就是一群熊孩子做游戏,第一个出队的人是编号为k的人.此后出队的人就是按照前一个人手里的编号.如果是正数+m就是这个人的左边的第m个人.如果是负数-m,就是 这个人的右边第m个人.由于这个人出队了.对下一个人有影响,所以+m的时候,是k+m-1.

codeforces CF920F SUM and REPLACE 线段树 线性筛约数

$ \Rightarrow $ 戳我进CF原题 F. SUM and REPLACE time limit per test: 2 seconds memory limit per test: 256 megabytes input: standard input output: standard output Let $ D(x) $ be the number of positive divisors of a positive integer $ x $ . For example, $

POJ 2528 (线段树+离散化) Mayor&#39;s posters

因为将每个单位都作为一个最小单元的话会爆内存的 所以,将海报的每个端点进行排序,将这些端点最为最小的区间. 毕竟是刚刚接触线段树,理解起来还有些吃力,还是那句话,题做多了慢慢就好了. 萌萌的AC代码君贴上. 1 //#define LOCAL 2 #include <iostream> 3 #include <algorithm> 4 #include <cmath> 5 using namespace std; 6 7 int n; 8 struct CPost 9

poj 2777 线段树的区间更新

Count Color Time Limit: 1000 MS Memory Limit: 65536 KB 64-bit integer IO format: %I64d , %I64u Java class name: Main [Submit] [Status] [Discuss] Description Chosen Problem Solving and Program design as an optional course, you are required to solve al

转载::POJ 2991 线段树+计算几何(有c++结构体操作)

POJ 2991 线段树+计算几何 (2011-02-27 21:13:44) 转载▼ 标签: 杂谈 分类: OI 话说这一题真的是很恶心很恶心,不过确实改变了我对线段树的一些看法,算是很经典的题目. 题意:有一个吊车由很多个不同长度的线段组成,一开始是一条长直线起点在(0,0),尾节点在(0,sum[n]),每条线段之间的夹角的初始值是180度.然后有一些操作a. b将第a条线段和a+1之间的夹角变成b度,经过每一次操作都要求出尾节点的坐标. 首先要用到一个计算几何的知识(没学过..请教而来)

poj 2750(线段树的动态规划)

Potted Flower Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 4186   Accepted: 1581 Description The little cat takes over the management of a new park. There is a large circular statue in the center of the park, surrounded by N pots of f