2014.10.6模拟赛【魔兽争霸】
来源:互联网 发布:重庆网络品牌建设平台 编辑:程序博客网 时间:2024/05/31 19:21
魔兽争霸(war.pas)
小x正在销魂地玩魔兽
他正控制着死亡骑士和n个食尸鬼(编号1~n)去打猎
死亡骑士有个魔法,叫做“死亡缠绕”,可以给食尸鬼补充HP
战斗过程中敌人会对食尸鬼实施攻击,食尸鬼的HP会减少
小x希望随时知道自己部队的情况,即HP值第k多的食尸鬼有多少HP,以便决定如何施放魔法
请同学们帮助他:)
小x向你发出3种信号:(下划线在输入数据中表现为空格)
A_i_a表示敌军向第i个食尸鬼发出了攻击,并使第i个食尸鬼损失了a点HP,如果它的HP<=0,那么这个食尸鬼就死了(Undead也是要死的……)。
敌军不会攻击一个已死的食尸鬼。
C_i_a 表示死亡骑士向第i个食尸鬼放出了死亡缠绕,并使其增加了a点HP。
HP值没有上限。
死亡骑士不会向一个已死的食尸鬼发出死亡缠绕
Q_k 表示小x向你发出询问
输入(war.in)
第一行,一个正整数 n
以后n个整数 表示n个食尸鬼的初始HP值
接着一个正整数m
以下m行 每行一个小x发出的信号
输出(war.out)
对于小x的每个询问,输出HP第k多的食尸鬼有多少HP,如果食尸鬼总数不足k个,输出-1。每个一行数。
最后一行输出一个数:战斗结束后剩余的食尸鬼数
样例
Input
Output
5
1 2 3
4 5
10
Q 2
A 4 6
C 1 4
Q 2
A 2 1
A 3 3
A 1 3
Q 4
C 2 10
Q 1
4
5
-1
11
3
约定
40%的数据 n<=3000 m<=5000
70%的数据 n<=8000 m<=10000
100%的数据 n<=30000 m<=50000
90%的数据随机生成
食尸鬼HP没有上限
数据保证任意时刻食尸鬼的HP值在longint范围内
数据保证A和C命令中的食尸鬼是活着的
输入数据中没有多余空格、换行
听说这是难度noip普及组的模拟赛啊……为毛有平衡树
支持三种操作:插入,删除,第k大。
还要保存一下原来编号i的食尸鬼在treap中的节点编号
唉考场上贴了模板结果后面处理的不对还是爆蛋
也就200行
#include<cstdio>#include<iostream>#include<cstring>#include<cstdlib>#include<algorithm>#include<cmath>#include<queue>#include<deque>#include<set>#include<map>#include<ctime>#define LL long long#define inf 0x7ffffff#define pa pair<int,int>#define pi 3.1415926535897932384626433832795028841971#define N 100010using namespace std;inline LL read(){ LL x=0,f=1;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} return x*f;}struct node{ int l,r,num,rando,sons,rep;}tree[N];int treesize,root,n,m,ans,tot;int from[N];void update(int now){ tree[now].sons = tree[tree[now].l].sons + tree[tree[now].r].sons + tree[now].rep;}void right_rotate(int &work){ int t = tree[work].l; tree[work].l = tree[t].r; tree[t].r = work; tree[t].sons = tree[work].sons; update(work); work = t;} void left_rotate(int &work){ int t = tree[work].r; tree[work].r = tree[t].l; tree[t].l = work; tree[t].sons = tree[work].sons; update(work); work = t;} int insert(int &now,int x){ if (now == 0) { now = ++treesize; tree[now].rando = rand(); tree[now].num = x; tree[now].rep=tree[now].sons = 1; return now; } tree[now].sons++; int save=now; if (tree[now].num==x) { tree[now].rep++; return now; } if (x < tree[now].num) { save=insert(tree[now].l,x); if (tree[tree[now].l].rando < tree[now].rando) right_rotate(now); } else { save=insert(tree[now].r,x); if (tree[tree[now].r].rando < tree[now].rando) left_rotate(now); } return save;} void del(int &now,int x){ if (now == 0) return; if (tree[now].num==x) { if (tree[now].rep>1) { tree[now].rep--; tree[now].sons--; return; } if (tree[now].l*tree[now].r==0) now=tree[now].l+tree[now].r; else if (tree[tree[now].l].rando<tree[tree[now].r].rando) { right_rotate(now); del(now,x); } else { left_rotate(now); del(now,x); } } else if (x>tree[now].num) { tree[now].sons--; del(tree[now].r,x); } else { tree[now].sons--; del(tree[now].l,x); }}int ask_rank(int now,int x){ if (now==0) return 0; if (tree[now].num==x) return tree[tree[now].l].sons+1; else if (x>tree[now].num) return tree[tree[now].l].sons+tree[now].rep+ask_rank(tree[now].r,x); else return ask_rank(tree[now].l,x);}int ask_num(int now,int x){if (tree[now].sons<x)return -1; if(now==0)return 0; if(x<=tree[tree[now].l].sons)return ask_num(tree[now].l,x); else if(x>tree[tree[now].l].sons+tree[now].rep)return ask_num(tree[now].r,x-tree[tree[now].l].sons-tree[now].rep); else return tree[now].num;}void succ(int now,int x){ if(now==0)return; if(tree[now].num<x){ans=tree[now].num;succ(tree[now].r,x);} else succ(tree[now].l,x);}void pred(int now,int x){ if(now==0)return; if(tree[now].num>x){ans=tree[now].num;pred(tree[now].l,x);} else pred(tree[now].r,x);}int main(){freopen("war.in","r",stdin);freopen("war.out","w",stdout);srand(time(0));n=read();tot=n;for (int i=1;i<=n;i++) { int x=read(); from[i]=insert(root,x); }m=read();for (int i=1;i<=m;i++){ char ch=getchar(); while (ch!='A'&&ch!='C'&&ch!='Q')ch=getchar(); if (ch=='Q') { int x=read(); if (x>tot)printf("-1\n"); else cout<<ask_num(root,tot-x+1)<<endl; } if (ch=='A') { int x=read(),y=read(); int fx=from[x],d=tree[fx].num; printf("%d %d\n",d,y); del(root,d); if (d-y<=0) { from[x]=-1; tot--; }else { from[x]=insert(root,d-y); } } if (ch=='C') { int x=read(),y=read(); int fx=from[x],d=tree[fx].num; del(root,d); from[x]=insert(root,d+y); }}printf("%d\n",tot);}
- 2014.10.6模拟赛【魔兽争霸】
- 魔兽争霸秘笈
- 魔兽争霸秘籍
- 魔兽争霸剧情
- 魔兽争霸系统
- 2014.10.6模拟赛【暗黑破坏神】
- 2014.10.6模拟赛【锻炼计划】
- 《魔兽争霸》故事背景
- 魔兽争霸III背景渊源
- 魔兽争霸古代编年史
- 面向对象与魔兽争霸
- 剑冢和魔兽争霸
- 魔兽争霸3秘籍代码
- 魔兽争霸没声音问题解决!
- 魔兽争霸作弊秘籍
- 魔兽争霸3秘籍代码
- 魔兽争霸英雄英语名称
- C++ Vs 魔兽争霸
- java 反射
- PHP+Mysql————表单数据插入数据库及数据提取
- git 常用命令
- mysql基本操作
- http和socket区别
- 2014.10.6模拟赛【魔兽争霸】
- Win7 X64 python3安装pycrypto, Unable to find vcvarsall.bat
- PE文件结构(五)基址重定位
- PAT 1005. 继续(3n+1)猜想
- linux下通过共享内存在进程之间实现通信(system V)
- 隐藏文本域的边框和改变文本框颜色
- androidannotations的background和UiThread配合使用参考
- 5种语言的按钮事件 断点
- getchar,scanf以及缓冲区的概念(转)