首页 > 代码库 > xjoi2016模拟题1

xjoi2016模拟题1

星期天下午被某个sb叫去做xjoi模拟题。

发现自己好弱。STL不熟。

T1

技术分享

 

一开始是想把每一列的最大平均值算出来,然后每一列相加在算平均值,然后发现这是错误的想法,于是华丽丽的10分。

正解:二分枚举最大平均值,判断是否合法。

#include<cstdio>
#include<cstdlib>
#include<cstring>
#define max(x,y) (x>y?x:y)
const int N=9001000;
long long sum[N];
int n,m;

int main()
{
    scanf("%d%d",&n,&m);
    double l=0.0,r,mid;
    for(int i=0;i<n;i++)
    {
        int x;
        for(int j=1;j<=m;j++)
        {
            scanf("%d",&x);
            if(r<(double)x) r=(double)x;
            if(j!=1) sum[m*i+j]=sum[m*i+j-1]+(long long)x;
            else sum[m*i+j]=(long long)x;
        }
    }

    while(l+0.000001<r)
    {
        mid=(l+r)/2.0;
        double yu=0.0,maxx;
        for(int i=0;i<n;i++)
        {
            maxx=-362913271.0;
            for(int j=1;j<=m;j++)
            maxx=max(sum[m*i+j]-j*mid,maxx);
            yu+=maxx;
        }
        if(yu<0) r=mid;
        else l=mid;
    }
    printf("%.4lf",mid);
}

T2

技术分享

 

因为两个节点相交那么他们第二列所连的第一列的位置一定是前一个的位置大于后一个的位置。

所以求出第二列所连的第一列的位置,然后求最长下降子序列。

#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
using namespace std;
const int N=100100;
int sa[N],sb[N],t[N],yu[N];
int n;
int maxx=0;

void findans()
{
    int len=0;
    for(int i=1;i<=n;i++)
    {
        
        int h;
        if(len==0||yu[len]<t[i]) yu[++len]=t[i];
        else {h=lower_bound(yu+1,yu+1+len,t[i])-yu;yu[h]=min(t[i],yu[h]);}

    }
    maxx=len;
}
int main()
{
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
    {
        int x;
        scanf("%d",&x);
        sa[x]=i;
    }
    for(int i=1;i<=n;i++)
    {
        int x;
        scanf("%d",&x);
        sb[i]=sa[x];
    }
    for(int i=1;i<=n;i++) t[i]=sb[n-i+1];
    findans();
    printf("%d",maxx);
}

T3

 

技术分享

看到题的时候脑海中只浮现了暴力二字。

然后发现其实进入节点是有序的,于是先用dfs序。

然后对于第一个操作,直接过一遍就好了。注意,要保存位置上是否有人。

对于第二个操作,用倍增找到离这个点最远的有人的父亲节点,答案就是两点的深度差。

STL打得我一脸mb

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<vector>
#include<algorithm>
#include<queue>
using namespace std;
const int N=100100;
int n,t;
vector<int>sa[N];
int anc[N][28],p[N],len=0;
void dfs(int x,int fa)
{
    //printf("%d %d\n",x,fa);
    //system("pause");
    anc[x][0]=fa;
    int h=sa[x].size();
    for(int i=0;i<h;i++)
    {
        
        if(sa[x][i]!=fa)
        {
            int y=sa[x][i];
            dfs(y,x);
        }
    }
    p[x]=++len;
}
void make_anc()
{
    for(int i=1;i<=20;i++)
    for(int j=1;j<=n;j++)
    anc[j][i]=anc[anc[j][i-1]][i-1];
}
int tf[N];
struct node{
    int x;
    node(){};
    node(int x):x(x){};
    bool operator<(const node&a) const {return p[x]>p[a.x];}
};
priority_queue<node>sb;
int find_ans(int x,int &ans)
{
    for(int i=20;x!=1&&i>=0;i--)
    if(anc[x][i]&&!tf[anc[x][i]])
    x=anc[x][i],ans+=(1<<i);
    return x;
}
int main()
{
    //memset(anc,-1,sizeof(anc));
    scanf("%d%d",&n,&t);
    for(int i=1;i<n;i++)
    {
        int x,y;
        scanf("%d%d",&x,&y);
        sa[x].push_back(y);
        sa[y].push_back(x);
    }
    for(int i=1;i<=n;i++) sort(sa[i].begin(),sa[i].end());
    //printf("!");
    dfs(1,0);make_anc();
    for(int i=1;i<=n;i++) sb.push(node(i)),tf[i]=1;
    
    for(int i=1;i<=t;i++)
    {
        int x,y,ans=0;
        scanf("%d%d",&x,&y);
        if(x==1)
        {
            node yu;
            while(y--)
            {
                yu=sb.top();sb.pop();
                tf[yu.x]=0;
            }
            ans=yu.x;
        }
        else
        {
            int yu=find_ans(y,ans);
            sb.push(node(yu));tf[yu]=1;
        }
        printf("%d\n",ans);
    }
}

xjoi2016模拟题1