今天成都突然下好大的雨啊233,我和zyc跑出去在操场跑了一圈多,刚出门三秒衣服就湿透了的那种雨,完了之后我还将就在墨池里游了几圈233,墨池的水好暖和,洗了澡之后才发现没有裤子换…
暑假第二次模拟赛,考的时候浑身舒服,三十分钟做完前两道题感觉自己要AK,然后第三题就挂了,震惊的是,第一题也挂了…难受…
题目
qu
【问题描述】
给你一个操作序列,问这个维护操作序列的数据结构是哪一种?
【输入格式】
第一行是一个正整数n代表操作数目。 接下来 n行,每行两个正整数opt,v。如果opt = 1,代表我们将v加入数据结构;如果opt= 2,代表我们从数据结构中取出了一个元素,这个元素的值是v。
【输出格式】
输出三行,第一行代表数据结构是否可能是栈,第二行代表数据结构是否可 能是队列,第三行代表数据结构是否可能大根堆。每一行的结果都只可能是“YES” 或者“No”。
【样例输入】
2 1 1 2 1
【样例输出】
YES
YES
YES
【样例解释】
╭︿︿︿╮
{/ o o /}
( (oo) )
︶︶︶
【数据规模与约定】
100%的数据满足1 ≤ n≤ 103。
题解:
显然直接模拟三个数据结构就可以了,我用的STL,注意两点,第一点…这点真坑,输出YES但是输出No,小写o,我就挂在这里了,还有一个要注意的是要判数据结构是否为空
AC代码
#include<cstdio>
#include<queue>
#include<stack>
#include<iostream>
#include<cstring>
using namespace std;
priority_queue<int>heapp;
queue<int>quee;
stack<int>stacc;
bool judge[10];
int n,opt,v;
int main(){
freopen("qu.in","r",stdin);
freopen("qu.out","w",stdout);
memset(judge,true,sizeof(judge));
scanf("%d",&n);
for(register int i=1;i<=n;i++){
scanf("%d%d",&opt,&v);
if(opt==1){
heapp.push(v);
quee.push(v);
stacc.push(v);
}else{
int temp;
if(heapp.size()==0){
judge[3]=false;
}else{
temp=heapp.top();heapp.pop();
if(temp!=v) judge[3]=false;
}
if(quee.size()==0){
judge[2]=false;
}else{
temp=quee.front();quee.pop();
if(temp!=v) judge[2]=false;
}
if(stacc.size()==0){
judge[1]=false;
}else{
temp=stacc.top();stacc.pop();
if(temp!=v) judge[1]=false;
}
}
if(judge[1]==false&&judge[2]==false&&judge[3]==false) break;
}
for(register int i=1;i<=3;i++){
if(judge[i]) printf("YES\n");
else printf("No\n");
}
return 0;
}
ming
【问题描述】
给你N个任务,对于第i个任务,我们需要ti的时间去完成它,它的 deadline 是di。如果我们设fi为第i个任务的完成时刻,那你需要做的便是确定每个任务的 开始时间,使得max((max(0,fi−di))最小化。(同一时间只能做一个任务)
【输入格式】
第一行一个整数N表任务的个数。 接下来N行每行两个整数,分别代表ti,di。
【输出格式】
一行一个整数代表最小化的max((max(0,fi−di))。
【样例输入】
2 1 1 2 2
【样例输出】
1
【样例解释】
╭︿︿︿╮
{/ o o /}
( (oo) )
︶︶︶
【数据规模与约定】
对于30%的数据,1 ≤ N≤ 10。 对于60%的数据,1 ≤ N≤ 103。 对于100%的数据,1 ≤N≤ 105。
题解:
显然第二题可以直接贪心,sort一遍然后贪就行了
AC代码
#include<cstdio>
#include<cstring>
#include<iostream>
#include<queue>
#include<vector>
#include<algorithm>
using namespace std;
int readin(){
int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9')ch=getchar();
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
struct Line{
int deadline,t;
}line[100000+10];
int N,tail;
bool cmp(const Line &A,const Line &B){return A.deadline<B.deadline;}
int main(){
freopen("ming.in","r",stdin);
freopen("ming.out","w",stdout);
N=readin();
int te,mp;
for(register int i=1;i<=N;i++){
te=readin();mp=readin();
tail++;
line[tail].deadline=mp;
line[tail].t=te;
}
sort(line+1,line+tail+1,cmp);
//for(register int i=1;i<=tail;i++) printf("%d\n",line[i].deadline);
int now=0;
int maxn=-1;
for(register int i=1;i<=tail;i++){
now+=line[i].t;
maxn=max(maxn,max(0,now-line[i].deadline));
}
printf("%d\n",maxn);
return 0;
}
zi
【问题描述】
我们有m+ 1棵树,分别是T0,T1,…,Tm。其中T0是一棵只有一个点的树,点 的编号为0。 生成第i棵树我们需要五个参数ai,bi,ci,di,li(ai,bi < i)。我们生成第i棵树是 将第ai棵树的ci号点和第bi棵树的di号点用一条长度为li的边连接起来形成的新 的树(不会改变原来两棵树)。下面我们需要对新树中的点重编号:对于原来在 第ai棵树中的点,我们不会改变他们的编号;对于原来在第bi棵树中的点,我们会将他们的编号加上第ai棵树的点的个数作为新的编号。 定义
其中,n为树Ti的大小,vi,vj是Ti中的点,d(vi,vj)代表这两个点的距离。现 在希望你求出∀1 ≤ i ≤ m,F(Ti)是多少。
【输入格式】
第一行一个整数m。 接下来每行五个整数ai,bi,ci,di,li代表第i棵树的生成方式。
【输出格式】
m行,每行一个整数,代表的值。
【样例输入】
3 0 0 0 0 2 1 1 0 0 4 2 2 1 0 3
【样例输出】
2 28 216
【样例解释】
╭︿︿︿╮
{/ o o /}
( (oo) )
︶︶︶
【数据规模与约定】
对于30%的数据,1 ≤ m ≤ 10。 对于60%的数据,每棵树的点数个数不超过105。 对于100%的数据,1 ≤ m ≤ 60。
这道题没有那么地显然,考试的时候看到我就不想写,当时想了一种暴力建树,树链剖分暴力处理询问的方法,代码应该至少200+,而且还只能得30分,点分也不知道最多能得多少分…但朴素的各种方法都很暴力,所以当时就直接看数学去了233。这道题正解的思路是这样的
令
F[Ti]
是
Ti
中每一对点的距离和,
ai,bi
表示
i
树由
其中 |Ttempi| 符号表示该数的size大小
设 A(Ti,u) 表示树 Ti 中所有点到 u 的距离和,
然后讨论u和v的位置,进行递归的分治往下枚举,即可得到结果,其中如果我们设 u∈Tai ,那么显然可以得到如下的结论
如果两个点 u,v 同时在 ai 中
如果两个点 u,v 分别一个在 ai 中一个在 bi 中,那么满足
AC代码
#include<cstdio>
#include<iostream>
#include<map>
#include<algorithm>
#include<utility>
using namespace std;
#define dnt long long
map<pair<int,int>,dnt> m;
map<pair<int,pair<int,int> >,dnt> d;
const int lk=1000000000+7;
long long size[100],ans[100];
struct order{
int a,b,c,d,l;
}order[100];
dnt D(dnt i,dnt u,dnt v){//计算Ti中u到v的距离
if(i==0||u==v) return 0;
map<pair<int,pair<int,int> >,dnt>::iterator it=d.find(make_pair(i,make_pair(u,v)));
if(it!=d.end()) return it->second;
dnt temp=0;
bool left_u=(u<size[order[i].a]),left_v=(v<size[order[i].a]);
if(left_u&&left_v) temp=D(order[i].a,u,v);
if(!left_u&&!left_v) temp=D(order[i].b,u-size[order[i].a],v-size[order[i].a]);
if(left_u&&!left_v) temp=(D(order[i].a,u,order[i].c)+order[i].l+D(order[i].b,v-size[order[i].a],order[i].d))%lk;
if(!left_u&&left_v) temp=(D(order[i].a,v,order[i].c)+order[i].l+D(order[i].b,u-size[order[i].a],order[i].d))%lk;
d[make_pair(i,make_pair(u,v))]=temp;
return temp;
}
dnt A(dnt i,dnt u){
if(i==0) return 0;
pair<int,int>p(i,u);
map<pair<int,int>,dnt>::iterator it=m.find(p);
if(it!=m.end()) return it->second;
if(u<size[order[i].a]) m[p]=((A(order[i].a,u)+A(order[i].b,order[i].d))%lk+size[order[i].b]*(order[i].l+D(order[i].a,u,order[i].c)))%lk;
else m[p]=(A(order[i].b,u-size[order[i].a])+(size[order[i].a]*(D(order[i].b,u-size[order[i].a],order[i].d)+order[i].l)%lk)%lk+A(order[i].a,order[i].c))%lk;
return m[p];
}
dnt F(dnt Ti,dnt Tai,dnt Tbi,dnt ci,dnt di,dnt li){
ans[Ti]=(ans[Tai]+ans[Tbi])%lk+(A(Tai,ci)*size[Tbi])%lk+(A(Tbi,di)*size[Tai])%lk+((size[Tai]*size[Tbi])%lk*li)%lk;
ans[Ti]%=lk;
return ans[Ti];
}
int main(){
freopen("zi.in","r",stdin);
freopen("zi.out","w",stdout);
size[0]=1;
int m;
scanf("%d",&m);
for(register int i=1;i<=m;i++){
scanf("%d%d%I64d%I64d%I64d",&order[i].a,&order[i].b,&order[i].c,&order[i].d,&order[i].l);
size[i]=(size[order[i].a]+size[order[i].b])%lk;
cout<<F(i,order[i].a,order[i].b,order[i].c,order[i].d,order[i].l)<<endl;
}
return 0;
}