【TJOI2014】电影评分(movie)

37 篇文章 0 订阅
7 篇文章 0 订阅

Description

这里写图片描述

Input

这里写图片描述

Output

对于每个询问输出答案

Sample Input

10
R 1 1 1
R 2 2 1 2
C 2 2
R 3 1 2
Q 1
C 3 2
C 1 5
Q 1
Q 2
Q 3

Sample Output

2
1
3
2

Solution

注意N<=10000

强烈谴责辣鸡出题人

强烈谴责辣鸡出题人

强烈谴责辣鸡出题人

什么辣鸡题,n应该要多一个0才对

首先,我打了一个三十分暴力,就是每个询问重新排序
代码如下

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cstring>
#define fo(i,a,b) for(int i=a;i<=b;i++)
#define N 101000
#define db double
using namespace std;
int id[N],act[N],fid[N],tot=0,n;
db sc[N];
struct node{
    db x;int y;
}a[N];
bool cnt(node x,node y){return (x.x>y.x)||(x.x==y.x && x.y<y.y);}
int main()
{
    freopen("movie.in","r",stdin);
    freopen("movie.out","w",stdout);
    scanf("%d\n",&n);
    fo(i,1,n)
    {
        char ch;scanf("%c",&ch);
        if(ch=='R')//---发布 
        {
            int x,y,z,mi=0;scanf("%d%d",&z,&x);
            id[++tot]=z;fid[z]=tot;
            fo(i,1,x)
            {
                scanf("%d",&y);
                mi=max(mi,act[y]);
                act[y]=tot;
            }
            sc[tot]=sc[mi];
            scanf("\n");
        }
        if(ch=='C')//---评分 
        {
            int x;db y;scanf("%d%lf\n",&x,&y);
            x=fid[x];sc[x]=(sc[x]+y)/2;
        }
        if(ch=='Q')//---查询 
        {
            fo(i,1,tot) a[i].x=sc[i],a[i].y=i;
            sort(a+1,a+tot+1,cnt);
            int x;scanf("%d\n",&x);
            printf("%d\n",id[a[x].y]);
        }
    }
}

很暴力对吧?
我在离比赛结束1分钟时交了这个暴力,因为我认为正解(splay)可能调不出来
在比赛还有10秒时,我调出了splay的样例,并提交
然后,它切了
接着,我想看看这个三十分暴力得了多少分
然后我发现我的三十分暴力得了100分????

辣鸡出题人

Code(splay)

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cstring>
#define fo(i,a,b) for(int i=a;i<=b;i++)
#define N 101000
#define db double
using namespace std;
int id[N],act[N],tot=0,t[N][2],fa[N],root,st[N],en[N],size[N],n,fid[N];
db sc[N];
bool cnt(int x,int y)
{
    if(x==0 || y==0) return 1;
    if(x==y) return 2;
    return (sc[x]>sc[y])||(sc[x]==sc[y] && x<y);
}
int lr(int x){return x==t[fa[x]][1];}
void update(int x)
{
    size[x]=size[t[x][0]]+size[t[x][1]]+1;
    if(t[x][0]) st[x]=st[t[x][0]];else st[x]=x;
    if(t[x][1]) en[x]=en[t[x][1]];else en[x]=x;
}
void rotate(int x)
{
    int y=fa[x],k=lr(x);
    t[y][k]=t[x][1-k];if(t[x][1-k]) fa[t[x][1-k]]=y;
    fa[x]=fa[y];if(fa[y]) t[fa[y]][lr(y)]=x;
    fa[y]=x;t[x][1-k]=y;
    update(y);update(x);
}
void splay(int x,int y)
{
    while(fa[x]!=y)
    {
        if(fa[fa[x]]!=y)
            if(lr(x)==lr(fa[x])) rotate(fa[x]);
            else rotate(x);
        rotate(x);
    }
    if(y==0) root=x;
}
int kth1(int r,int x)
{
    if(x==r) return en[t[r][0]];
    if(cnt(x,r)&&cnt(st[t[r][1]],x)) return r;
    if(cnt(x,r)) return kth1(t[r][1],x);
    else return kth1(t[r][0],x);
}
int kth2(int r,int x)
{
    if(x==r) return st[t[r][1]];
    if(cnt(r,x)&&cnt(x,en[t[r][0]])) return r;
    if(cnt(x,r)) return kth2(t[r][1],x);
    else return kth2(t[r][0],x);
}
void ins(int z)
{
    int x=kth1(root,z),y=kth2(root,z);
    splay(x,0);splay(y,x);
    fa[z]=y;t[y][0]=z;
    splay(z,0);
}
int kth(int r,int x)
{
    if(size[t[r][0]]+1==x) return r;
    if(x<=size[t[r][0]]) return kth(t[r][0],x);
    else return kth(t[r][1],x-size[t[r][0]]-1);
}
int main()
{
    freopen("movie.in","r",stdin);
    freopen("movie.out","w",stdout);
    scanf("%d\n",&n);
    fa[n+1]=n+2;t[n+2][0]=n+1;
    sc[n+1]=-1;sc[n+2]=10;
    update(n+1);update(n+2);root=n+2;
    fo(i,1,n)
    {
        char ch;scanf("%c",&ch);
        if(ch=='R')//---发布 
        {
            int x,y,z,mi=0;scanf("%d%d",&z,&x);
            id[++tot]=z;fid[z]=tot;
            fo(i,1,x)
            {
                scanf("%d",&y);
                mi=max(mi,act[y]);
                act[y]=tot;
            }
            sc[tot]=sc[mi];
            ins(tot);
            scanf("\n");
        }
        if(ch=='C')//---评分 
        {
            int x;db z;scanf("%d%lf\n",&x,&z);
            x=fid[x];z=(z+sc[x])/2.0;
            int x1=kth1(root,x),x2=kth2(root,x);
            splay(x1,0);splay(x2,x1);
            fa[t[x2][0]]=0;t[x2][0]=0;
            splay(x2,0);
            sc[x]=z;ins(x);
        }
        if(ch=='Q')//---查询 
        {
            int z;scanf("%d\n",&z);
            z=kth(root,tot-z+2);
            printf("%d\n",id[z]);
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值