bzoj5159 [Tjoi2014]电影评分

原创 2018年04月17日 13:21:26

http://www.elijahqi.win/archives/3114
题目描述

小Z发明了一套新的电影评分系统。这套系统有三种操作:发布新电影、对电影评分、以及询问电影评分的排名。具体是这样运作的:如果是发布新电影,并且这部电影的有所主演之前均没有出现过,那么这部新电影的评分为0,否则这部电影的评分为最近一部与该电影至少有一个共同主演的电影的评分;如果是对电影进行评分,那么这部电影的评分就变成之前评分与新的评分的平均数;如果是查询排名,则根据评分输出相应排名。评分最高的为第一名。如果有多部电影分数相同,那么输出最早的一部。电影的评分在0到5之间。

输入输出格式

输入格式:

输入的第一行是n,表示操作次数。接下来n行,每一行是以下三种操作之一:

Q x:查询当前排名为x的电影ID
R ID x actor1 actor2 …· actorx:发布新电影ID,该电影有x个主演分别为 actor1, actor2,…’
C ID score:评分操作,表示对电影ID的评分为 score
数据保证每个电影的ID不相同,且每部电影至多不超过5名主演。

1≤ actor1, actor2,··≤10^5

1≤ID≤10^5

输出格式:

对于每一个查询操作,输出相应排名的电影的ID。

输入输出样例

输入样例#1: 复制

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
输出样例#1: 复制

2
1
3
2
说明

样例解释
Movie 1 2 3
0 - -
0 0 -
0 1 -
0 1 1
Q 1 => 2 //Movie 2 wa s released be fore Movie 3
0 1 1.5
2.5 1 1.5
Q 1 => 1
Q 2 => 3
Q 3 => 2
数据范围
对于 30% 的数据,n ≤ 100

对于 100% 的数据,n ≤ 10000

将小数写成二进制位 用后缀平衡树模拟小数的比较过程

考虑这题的要求一定是取平均数那么也就是我每回/2 相当于将二进制下的小数整体向后面移动一位 然后再看整数部分是奇数还是偶数来判定我新加的一位是0还是1 那么就用sa表示我这个数的小数部分 fir表示我这一位是谁 然后sec表示我的后半部分是链接到哪个fir和sec组成的二元组上了 注意每次比较的时候需要先看一看原序列是否存在这样的高精度小数 然后再判断是否要新加入 对于在后缀平衡树上如何o(1)比较 那就是我需要记录一个标记 tag 若当前节点管辖范围是l~r那么他的标记是l+r>>1 他左区间的标记都会小于(l+r>>1) 右区间的标记都会大于(l+r>>1) 然后因为这个标记不好维护 所以每次修改的时候暴力重构即可 复杂度是对的

用一棵splay来存这个的整数部分 然后splay上的比较函数需要重新新写一个才可以

#include<cstdio>
#include<cctype>
#include<algorithm>
#define ll long long
using namespace std;
inline char gc(){
    static char now[1<<16],*S,*T;
    if (T==S){T=(S=now)+fread(now,1,1<<16,stdin);if (T==S)return EOF;}
    return *S++;
}
inline int read(){
    int x=0,f=1;char ch=gc();
    while(!isdigit(ch)) {if (ch=='-') f=-1;ch=gc();}
    while(isdigit(ch)) x=x*10+ch-'0',ch=gc();
    return x*f;
}
const int N=1e5+100;
const int inf=0x3f3f3f3f;
int size[N],fa[N],c[N][2],n,num,cnt,v[N],tim[N],flag,root;
int lc[N],rc[N],fir[N],sec[N],sa[N],rd[N],last[N],rt;int tag[N];
inline void update(int x){
    size[x]=size[c[x][0]]+size[c[x][1]]+1;
}
inline void rotate(int x,int &tar){
    int y=fa[x],z=fa[y],l=c[y][1]==x,r=l^1;
    if (y==tar) tar=x;else c[z][c[z][1]==y]=x;
    fa[c[x][r]]=y;fa[y]=x;fa[x]=z;
    c[y][l]=c[x][r];c[x][r]=y;update(y);update(x);
}
inline void splay(int x,int &tar){
    while(x!=tar){
        int y=fa[x],z=fa[y];
        if (y!=tar){
            if (c[y][0]==x^c[z][0]==y) rotate(x,tar);else rotate(y,tar);
        }rotate(x,tar);
    }
}
inline bool check(int id1,int id2){
    if (v[id1]>v[id2]) return 1;if (v[id1]<v[id2]) return 0;
    if (tag[sa[id1]]>tag[sa[id2]]) return 1;
    if (tag[sa[id1]]<tag[sa[id2]]) return 0;
    return tim[id1]<tim[id2];
}
inline void insert1(int &x,int id,int f){
    if (!x) {x=id;fa[x]=f;size[x]=1;splay(x,root);return;}
    if (check(id,x)) insert1(c[x][0],id,x);else insert1(c[x][1],id,x);
}
inline int find(int x,int k){
    int l=c[x][0],r=c[x][1];
    if (size[l]+1==k) return x;
    if (k<=size[l]) return find(l,k);else return find(r,k-size[l]-1);
}
inline void del(int x){
    splay(x,root);static int pre,succ;
    if (c[x][1]*c[x][0]==0){
        root=c[x][1]+c[x][0];if (c[x][1]) c[x][1]=0;
        if (c[x][0]) c[x][0]=0;fa[root]=0;return;
    }
    pre=c[x][0],succ=c[x][1];
    while(c[pre][1]) pre=c[pre][1];
    while(c[succ][0]) succ=c[succ][0];
    splay(succ,root);splay(pre,c[succ][0]);
    c[pre][1]=fa[c[pre][1]]=0;update(pre);update(root);
}
inline void rebuild(int x,int l,int r){
    int mid=l+r>>1;if (lc[x]) rebuild(lc[x],l,mid);
    if (rc[x]) rebuild(rc[x],mid+1,r);tag[x]=l+r>>1;
}
inline void lrotate(int &x,int L,int R){
    int r=rc[x];rc[x]=lc[r];lc[r]=x;x=r;rebuild(x,L,R);
}
inline void rrotate(int &x,ll L,ll R){
    int l=lc[x];lc[x]=rc[l];rc[l]=x;x=l;rebuild(x,L,R);
} 
inline int check1(int id1,int id2){
    if (fir[id1]>fir[id2]) return 0;if (fir[id1]<fir[id2]) return 1;
    if (tag[sec[id1]]>tag[sec[id2]]) return 0;if (tag[sec[id1]]<tag[sec[id2]]) return 1;
    return 2;
}
inline void insert2(int &x,int l,int r){
    if (!x) {x=num;rd[x]=rand();lc[x]=rc[x]=0;tag[x]=l+r>>1;return;}
    if(check1(num,x)==2) {flag=x;return;}
    int mid=l+r>>1;
    if (check1(num,x)) {
        insert2(lc[x],l,mid);
        if(rd[lc[x]]>rd[x]) rrotate(x,l,r);return;
    }insert2(rc[x],mid+1,r);
    if (rd[rc[x]]>rd[x]) lrotate(x,l,r);    
}
inline void print(int x){
    if (!x) return;
    if (c[x][0]) print(c[x][0]);
    printf("%d %d %lld\n",x,v[x],tag[sa[x]]);
    if (c[x][1]) print(c[x][1]);
}
inline void print1(int x){
    if (!x) return;
    printf("%d ",fir[x]);print1(sec[x]);
}
int main(){
    freopen("bzoj5159.in","r",stdin);
//  freopen("bzoj5159.out","w",stdout);
    n=read();srand(20010820);
    for (int ii=1;ii<=n;++ii){static int x,nm,now,act;
        char ch=gc();while(ch!='Q'&&ch!='C'&&ch!='R') ch=gc();//print(root);puts("---");
        if (ch=='Q'){printf("%d\n",find(root,read()));continue;}
        if (ch=='R'){
            x=read();nm=read();now=0;
            for (int i=1;i<=nm;++i){
                act=read();if (tim[last[act]]>tim[now]) now=last[act];last[act]=x;
            }v[x]=v[now];sa[x]=sa[now];tim[x]=++cnt;insert1(root,x,root);continue;
        }
        if (ch=='C'){
            x=read();nm=read();del(x);v[x]+=nm;
            if (sa[x]||v[x]&1){
                fir[++num]=v[x]&1;sec[num]=sa[x];// sec link to sa

                sa[x]=num;//print1(sa[x]);puts("decimal");
                flag=0;insert2(rt,1,inf);if (flag) --num,sa[x]=flag;

            //  if (x==73611) print1(sa[7213]),puts("decimal");
            }v[x]>>=1;insert1(root,x,root);//print(root);
        }
    }
    return 0;
}
版权声明:辣鸡蒟蒻的blog https://blog.csdn.net/elijahqi/article/details/79973432

【TJOI2014】电影评分(movie)

DescriptionInputOutput对于每个询问输出答案Sample Input10 R 1 1 1 R 2 2 1 2 C 2 2 R 3 1 2 Q 1 C 3 2 C 1 ...
  • u011056504
  • u011056504
  • 2017-04-01 22:01:35
  • 718

bzoj5154~bzoj5159 【TJOI2014】

bzoj5154 (Day1T1)匹配 【题意】 左右各nnn个点的二分图,求完美匹配的交集 【数据范围】 n≤80n≤80n\leq80 【思路】 求出一个完美匹配,再枚举完美匹配上每条...
  • leolyun
  • leolyun
  • 2018-02-12 10:57:40
  • 1363

【TJOI2014】[JZOJ3744] 电影评分

Description Solution辣鸡TJOI出题人,毁我青春这题很明显可以用Splay做,双关键字维护,直接按照给的操作做就行了。 据说有高级离线做法?我比较蠢不会。然而因为暴力修改和...
  • hzj1054689699
  • hzj1054689699
  • 2017-04-02 15:29:51
  • 631

python爬虫之豆瓣电影评分

想知道一部电影好不好看,豆瓣的评分还是比较靠谱的,于是,搞了搞,写了一个小爬虫: # -*- coding: utf-8 -*- import urllib2 import re import ...
  • wangzhuo0978
  • wangzhuo0978
  • 2016-08-29 19:07:22
  • 1432

python 计算男女电影标准差 coursera男女电影评分差异分析编程

最近学习AI的强有力工具Python。 看到南京大学 的 用python玩转数据视频,有一个计算标准差的作业,现分享如下 import pandas as pd # 导入评分数据 rati...
  • wwangfabei1989
  • wwangfabei1989
  • 2018-01-19 20:41:17
  • 169

基于R语言构建的电影评分预测模型

电影评分系统是一种常见的推荐系统。现在使用R语言基于协同过滤算法来构建一个电影评分预测模型。 一,前提准备         1.R语言包:ggplot2包(绘图),recommenderlab包,re...
  • wzgl__wh
  • wzgl__wh
  • 2016-08-05 02:25:53
  • 6374

电影评分-数据集

  • 2016年01月22日 14:58
  • 18.12MB
  • 下载

电影评分次数Top10问题

问题还原:求被评分次数最多的10部电影,并给出评分次数(电影名,评分次数)ratings.dat 用户ID,电影ID,评分,评分时间戳 1::1193::5::978300760 movies.dat...
  • zyz_home
  • zyz_home
  • 2018-03-21 21:46:55
  • 63

电影评分预测

电影评分预测
  • Hsuan816
  • Hsuan816
  • 2016-11-30 17:27:16
  • 1084

推荐系统—影视评分预测

本文根据Andrew Ng的Machine Learning的课写就。 =======================================一、预测电影评分============...
  • LiFeitengup
  • LiFeitengup
  • 2013-06-26 12:28:27
  • 7233
收藏助手
不良信息举报
您举报文章:bzoj5159 [Tjoi2014]电影评分
举报原因:
原因补充:

(最多只允许输入30个字)