Wannafly模拟赛4 A,B,D解题报告
A.LapTop
题目描述
FST是一名可怜的小朋友,他很强,但是经常fst,所以rating一直低迷。
但是重点在于,他非常适合ACM!并在最近的区域赛中获得了不错的成绩。
拿到奖金后FST决定买一台新笔记本,但是FST发现,在价格能承受的范围内,笔记本的内存和速度是不可兼得的。
可是,有一些笔记本是被另外一些“完虐”的,也就是内存和速度都不高于另外某一个笔记本,现在FST想统计一下有多少笔记本被“完虐”。
输入描述:
第一行一个正整数n,
表示笔记本的数量。接下来n行,每行两个正整数Mi,Si表示这款笔记本的内存和速度。
n≤105,Mi,Si≤109
输出描述:
一行,一个正整数,表示被完虐的笔记本数。
输入
4
100 700
200 500
50 100
300 400
输出
1
大致思路:
对于每一个笔记本都有两个值,先对于任意一个值进行排序。
然后建立线段树,统计区间另一个最大值。
然后从后往前扫,每次扫描当前位置到最后一个的区间之内有没有比另一个值大的,如果有ans++
代码:
1 #include<bits/stdc++.h> 2 using namespace std; 3 const int INF=1<<30; 4 const int maxn=1e5+7; 5 struct Node{ 6 int m,s; 7 }node[maxn]; 8 int tree[maxn<<2]; 9 void build(int l,int r,int k) 10 { 11 //cout<<k<<endl; 12 if(l>r) 13 return ; 14 if(l==r){ 15 tree[k]=node[l].s; 16 return ; 17 } 18 int mid=(l+r)>>1; 19 build(l,mid,k<<1); 20 build(mid+1,r,k<<1|1); 21 tree[k]=max(tree[k<<1],tree[k<<1|1]); 22 } 23 int query(int l,int r,int ql,int qr,int k) 24 { 25 if(l>r||ql>r||qr<l) 26 return -INF; 27 if(ql<=l&&qr>=r) 28 return tree[k]; 29 int mid=(l+r)>>1; 30 return max(query(l,mid,ql,qr,k<<1),query(mid+1,r,ql,qr,k<<1|1)); 31 } 32 bool cmp(Node a,Node b) 33 { 34 return a.m<b.m; 35 } 36 int main() 37 { 38 //freopen("in.txt","r",stdin); 39 ios::sync_with_stdio(false); 40 memset(tree,0,sizeof(tree)); 41 int n,ans=0; 42 cin>>n; 43 for(int i=0;i<n;++i) 44 cin>>node[i].m>>node[i].s; 45 sort(node,node+n,cmp); 46 build(0,n-1,1); 47 for(int i=n-2;i>=0;--i){ 48 int x=query(0,n-1,i,n-1,1);//区间查询 49 //cout<<x<<" "<<i<<endl; 50 if(x>node[i].s) 51 ans++; 52 } 53 cout<<ans<<endl; 54 return 0; 55 }
B.Distance
题目描述
FST作为小朋友,经常会遇到和距离有关的问题,但是他已经厌倦了曼哈顿距离和欧几里德距离,所以FST就定义了一种FST距离。
这种距离并不用于空间或平面中,而运用于FST发明的一些神奇的算法中(唔... ...)。
设i号元素的特征值为Ai,则i和j的FST距离是 |i2 - j2|+|Ai2 - Aj2|。
为了实现某新的数据结构,FST想在一大堆元素中找出距离最大的一对元素,他不关心是哪一对元素,只想求出最大距离。
输入描述:
第一行,一个正整数n,为元素个数。
第二行,n个正整数Ai为这n个元素的特征值。
输出描述:
一行,一个正整数表示最大距离。long long请用lld
输入
2
4 3
输出
10
备注:
n≤1e5,Ai≤1e9
大致思路:
对于原式,很容易地分类讨论出两种情况,从而将绝对值号去掉
从而分别统计Ai^2+i^2的最大最小值和Ai^2-i^2的最大最小值
分别将最大最小值相减,取一个abs,再在两个情况中取一个max,就是答案
代码:
1 #include<bits/stdc++.h> 2 using namespace std; 3 typedef long long ll; 4 const int maxn=1e5+7; 5 const long long INF=1e20; 6 struct Node{ 7 ll a,id; 8 ll m1,m2; 9 }node[maxn]; 10 int main() 11 { 12 ios::sync_with_stdio(false); 13 //freopen("in.txt","r",stdin); 14 int n; 15 cin>>n; 16 for(int i=1;i<=n;++i){ 17 cin>>node[i].a; 18 node[i].id=i; 19 node[i].m1=1ll*i*i+node[i].a*node[i].a;//记得乘1ll 20 node[i].m2=1ll*i*i-node[i].a*node[i].a; 21 } 22 ll min1=INF,min2=INF,max1=-INF,max2=-INF; 23 for(int i=1;i<=n;++i){ 24 max1=max(max1,node[i].m1); 25 min1=min(min1,node[i].m1); 26 max2=max(max2,node[i].m2); 27 min2=min(min2,node[i].m2); 28 } 29 ll ans1=abs(max1-min1),ans2=abs(max2-min2); 30 cout<<max(ans1,ans2)<<endl; 31 return 0; 32 }
D.Fancy Signal Translate
题目描述
FST是一名可怜的小朋友,他很强,但是经常fst,所以rating一直低迷。
但是重点在于,他真的很强!他发明了一种奇特的加密方式,这种加密方式只有OIer才能破解。
这种加密方式是这样的:对于一个01串,他会构造另一个01串,使得原串是在新串中没有出现过的最短的串。
现在FST已经加密好了一个串,但是他的加密方式有些BUG,导致没出现过的最短的串不止一个,他感觉非常懊恼,所以他希望计算出没出现过的最短的串的长度。
输入描述:
一行,一个01串。长度≤105
输出描述:
一行,一个正整数,表示没有出现过的最短串的长度。
输入
100010110011101
输出
4
大致思路:
因为字符串的长度最长不超过1e5,所以01串的长度时很小的,最多大概在13。
所以就可以以字符串的每一位开始,建立长度不超过13的字典树。
然后对于字典树进行BFS,找到第一个没有完整子节点的节点为止,答案就是那个节点的深度
代码:
1 #include<bits/stdc++.h> 2 using namespace std; 3 const int maxn=1e5+7; 4 typedef pair<int,int> pii; 5 struct Tree{ 6 struct Node{ 7 int next[2]; 8 }node[maxn<<2]; 9 int size; 10 void init() 11 { 12 for(int i=0;i<maxn<<2;++i){ 13 memset(node[i].next,0,sizeof(node[i].next)); 14 } 15 size=1; 16 } 17 void insert(char *s) 18 { 19 int now=0; 20 for(int i=0;i<13;++i){ 21 if(s[i]=='\0') 22 return ; 23 int x=s[i]-'0'; 24 if(!node[now].next[x]) 25 node[now].next[x]=size++; 26 now=node[now].next[x]; 27 } 28 } 29 int sear() 30 { 31 queue<pii> q; 32 q.push(make_pair(0,1)); 33 while(!q.empty()) 34 { 35 pii u=q.front(); 36 int x=u.first; 37 int k=u.second; 38 q.pop(); 39 for(int i=0;i<2;++i){ 40 if(node[x].next[i]) 41 q.push(make_pair(node[x].next[i],k+1)); 42 else 43 return k; 44 } 45 } 46 return 13; 47 } 48 }Tree; 49 char str[maxn]; 50 int main() 51 { 52 ios::sync_with_stdio(false); 53 //freopen("in.txt","r",stdin); 54 Tree.init(); 55 cin>>str; 56 int len=strlen(str); 57 for(int i=0;i<len;++i) 58 Tree.insert(str+i); 59 cout<<Tree.sear()<<endl; 60 return 0; 61 }