2018西安电子科大同步赛
题目描述
输入描述:
第一行输入一个T,表示王萌萌询问的单词。(T <= 20)
后面T行每行一个英文单词,题目保证英文单词是[0, 10]数字所表示的单词且单词书写无误,单词用小写形式给出。
输出描述:
对于每一个输入的单词,输出它的中文读音,请用小写形式给出。
输入
5 zero one one four eight
输出
ling yi yi si ba
水题。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<bits/stdc++.h> 2 #define clr(x) memset(x,0,sizeof(x)) 3 using namespace std; 4 string e[11]={"zero","one","two","three","four","five","six","seven","eight","nine","ten"}; 5 string c[11]={"ling","yi","er","san","si","wu","liu","qi","ba","jiu","shi"}; 6 map<string,string> etoc; 7 string s; 8 int n; 9 int main() 10 { 11 for(int i=0;i<=10;i++) 12 etoc[e[i]]=c[i]; 13 ios::sync_with_stdio(false); 14 cin>>n; 15 for(int i=1;i<=n;i++) 16 { 17 cin>>s; 18 cout<<etoc[s]<<endl; 19 } 20 return 0; 21 }
题目描述
输入描述:
包含多组测试数据,每组数据开始一行包含不超过20个字母,表示游戏给出的字母。
接下来是一行一个数字N(1 <= N <= 1000)
接下来N行,每行一个字符串表示词典中的单词,单词长度不会超过10。
输出描述:
每组数据输出一行,表示最长可能拼出的单词长度,如果一个单词都拼不出,那就输出0。
输入
masterblodpo 7 boogie magnolia punch blood master inherent phantom ablderrivala 5 arrival blade runner incendies sicario
输出
6 7
水题。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<bits/stdc++.h> 2 #define clr(x) memset(x,0,sizeof(x)) 3 using namespace std; 4 const int N=1e2+10; 5 const int type=26; 6 char s[N]; 7 int num[type],sum[type]; 8 int n,m,ans; 9 int main() 10 { 11 while(scanf("%s",s)!=EOF) 12 { 13 ans=0; 14 clr(num); 15 for(int i=0;s[i];i++) 16 num[s[i]-'a']++; 17 scanf("%d",&n); 18 for(int i=1;i<=n;i++) 19 { 20 scanf("%s",s); 21 clr(sum); 22 for(int j=0;s[j];j++) 23 sum[s[j]-'a']++; 24 int j; 25 for(j=0;j<type;j++) 26 if(sum[j]>num[j]) 27 break; 28 if(j==type) 29 ans=max(ans,(int)strlen(s)); 30 } 31 printf("%d\n",ans); 32 } 33 return 0; 34 }
题目描述
Arch0n老师is a rich man, 他靠自己的才华和智商年纪轻轻就赚了不少钱。为了训练自己的智商,他经常玩一些interesting的游戏来训练自己的智商,比如什么RGB游戏,还有和妹子一块玩Don't Starve。言归正传,今天他又发明了一个新的interesting game。
Ar老师手上有一堆卡牌,然后卡牌上写了一个数字Ai(正整数),当前他有n张牌,然后他总是随机取出两张来,然后他一眼就能看出这两牌中哪一张小(相同就取相同的,这操作好像对于Ar老师来说太简单了),作为这两张牌的有效分值,然后呢他陷入了沉思,对于n张牌取两张牌显然有确定的组合可能性,有n*(n-1)/2对组合,然后他想知道所有这些组合中第k大的分值是多少。
输入描述:
输入一个t表示数据组数;(0<t<=10)
接下来一行是n,k,表示n张牌和最后第k大的分值;(1<n<2500,保证0<k<=n*(n-1)/2)
接下来一行是n个值ai,表示第i张牌上的数字(0 < ai <= 10000000)。
输出描述:
每组数据输出一行,即第k大的分值为多少。
水题。不过被输出格式lld坑到了,习惯用的I64d竟然不算过。。。。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<bits/stdc++.h> 2 #define clr(x) memset(x,0,sizeof(x)) 3 using namespace std; 4 const int N=5e3+10; 5 int a[N]; 6 int n,k,m,T,t; 7 int main() 8 { 9 scanf("%d",&T); 10 while(T--) 11 { 12 scanf("%d%d",&n,&k); 13 for(int i=1;i<=n;i++) 14 scanf("%d",a+i); 15 sort(a+1,a+n+1); 16 t=n; 17 k=n*(n-1)/2-k+1; 18 int i; 19 for(i=1;i<=n;i++) 20 { 21 t--; 22 k-=t; 23 if(k<=0) 24 break; 25 } 26 printf("%d\n",a[i]); 27 } 28 return 0; 29 }
题目描述
输入描述:
有多组输入数据,第一行为一个数字T,代表有T组输入数据 (0<T≤20)。
接下来为T组数据。
每组测试数据分2行:
第一行为n,表示有n个数(1≤n≤100)
接下来的一行有n个正整数ai,表示初始的n个数(1≤ai≤10000,1≤i≤n)。
输出描述:
对于每组数据,在一行上输出最后剩下数的期望值的整数部分。
输入
2 3 1 1 1 2 2 3
输出
1 2
瞎jb猜结论题,结论就是Σai/n。感兴趣的话可以自己证明下。证明思路就是算每个数除以2的次数的概率,然后算出每个数在对应除以2的概率下的除以2出来的数的期望的和。因为你拿两个数相加/2就相当于各自/2。不过这道题很人性,忽略小数点后于是就有这样的结论了。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<bits/stdc++.h> 2 #define clr(x) memset(x,0,sizeof(x)) 3 using namespace std; 4 const int N=5e3+10; 5 int n,k,m,T,t; 6 int main() 7 { 8 scanf("%d",&T); 9 while(T--) 10 { 11 m=0; 12 scanf("%d",&n); 13 for(int i=1;i<=n;i++) 14 { 15 scanf("%d",&t); 16 m+=t; 17 } 18 printf("%d\n",m/n); 19 } 20 return 0; 21 }
题目描述
为了改变这一现状,他random了一个01串,并从中截取了一段作为自己的口令。
他选择的口令满足以下条件:
1. 口令串表示的二进制数在十进制下可以被表示为3k(k>=0)。
2. 口令串可以有前导零。
现已经random出了01串,他想知道有多少种口令方案可以选择(不同的子段即为不同)。
输入描述:
若干组数据,每组数据仅一行01串s,表示random出来的的串,|s|<=1e6。
输出描述:
输出口令的方案数。
首先用hash的想法做这题。我们从最低位反向求s[n-1]~s[i]的01串%3的值,对应hashed[i]。那么任意一串可以表示为(hashed[h]-hashed[t-1])/2^(n-t) %3,h为串头位置,t为串尾位置,2^(n-t)即为他要把整个值左移n-t位。模3意义下为0即为3k。
然后我们发觉2对3的逆元还是2。那么除以2就相当于乘以2。假如一个数不为0,它在%3下乘2它会始终是2,1,2,1,2,1这样的循环。因此我们上式中要求hashed[h]和hashed[t-1]相同,不然相减后的数永不可能为0.也就永远不能表示为3k。
所以我们统计下各个不同hashed值i的位置数num[i](包括第n位hashed为0),那么不同i对答案的贡献为任意选俩该数值的位置的数量,即num[i]*(num[i]-1)/2。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<bits/stdc++.h> 2 #define clr(x) memset(x,0,sizeof(x)) 3 #define LL long long 4 using namespace std; 5 const int N=1e6+10; 6 int n,m,p; 7 LL ans; 8 char s[N]; 9 int hashed[N]; 10 int num[3]; 11 int main() 12 { 13 while(scanf("%s",s)!=EOF) 14 { 15 n=strlen(s); 16 m=0; 17 for(int i=n-1;i>=0;i--) 18 { 19 p=s[i]-'0'; 20 p=((n-1-i)&1)?p:(2*p%3); 21 m=(m+p)%3; 22 hashed[i]=m; 23 } 24 hashed[n]=0; 25 clr(num); 26 for(int i=n;i>=0;i--) 27 num[hashed[i]]++; 28 ans=0; 29 for(int i=0;i<3;i++) 30 if(num[i]>1) ans+=1LL*num[i]*(num[i]-1)/2; 31 printf("%lld\n",ans); 32 } 33 return 0; 34 }
题目描述
输入描述:
多组数据,请处理到输入结束。
每组数据,第一行为三个整数N,M,Q (0 < N,M,Q <= 50000)
接下来一行Q个数,表示用户请求的页面编号。
输出描述:
对于每组数据,输出一个数,表示最少的缺页次数。
手写最佳页面置换算法23333。拿一个堆去维护当前最晚出现结点的值,并对每个页面在堆中的点的位置记录。然后去维护这个堆,每次缺页删去根节点。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<bits/stdc++.h> 2 #define clr(x) memset(x,0,sizeof(x)) 3 #define LL long long 4 #define INF 0x3f3f3f3f 5 using namespace std; 6 const int N=1e5+10; 7 int n,m,q,t,ans; 8 int nexted[N],pre[N],hashed[N]; 9 int que[N]; 10 struct node{ 11 int len,num; 12 }heap[N<<2]; 13 int tot,all; 14 int add(int n,int len) 15 { 16 if(len<0) len=INF; 17 heap[++tot]=(node){len,n}; 18 int p=tot; 19 while(p>1 && heap[p].len>heap[p>>1].len) 20 { 21 swap(heap[p],heap[p>>1]); 22 p>>=1; 23 } 24 return p; 25 } 26 int change(int has,int len) 27 { 28 if(len<0) len=INF; 29 int p=has; 30 heap[p].len=len; 31 while(p>1 && heap[p].len>heap[p>>1].len) 32 { 33 swap(heap[p],heap[p>>1]); 34 p>>=1; 35 } 36 int maxn; 37 while(heap[p].len<heap[p<<1].len || heap[p].len<heap[p<<1|1].len) 38 { 39 maxn=heap[p<<1|1].len>heap[p<<1].len?(p<<1|1):(p<<1); 40 swap(heap[p],heap[maxn]); 41 p=maxn; 42 } 43 return p; 44 } 45 int pop() 46 { 47 int rt=heap[1].num; 48 heap[1]=heap[tot]; 49 tot--; 50 int p=1; 51 int maxn; 52 while(heap[p].len<heap[p<<1].len || heap[p].len<heap[p<<1|1].len) 53 { 54 maxn=heap[p<<1|1].len>heap[p<<1].len?(p<<1|1):(p<<1); 55 swap(heap[p],heap[maxn]); 56 p=maxn; 57 } 58 return rt; 59 } 60 int main() 61 { 62 while(scanf("%d%d%d",&n,&m,&q)!=EOF) 63 { 64 clr(pre); 65 clr(hashed); 66 clr(heap); 67 tot=0; 68 all=0; 69 ans=0; 70 for(int i=1;i<=q;i++) 71 { 72 scanf("%d",que+i); 73 nexted[i]=-1; 74 if(pre[que[i]]) 75 nexted[pre[que[i]]]=i; 76 pre[que[i]]=i; 77 } 78 for(int i=1;i<=q;i++) 79 { 80 if(all<n) 81 { 82 if(!hashed[que[i]]) 83 { 84 hashed[que[i]]=add(que[i],nexted[i]); 85 all++; 86 } 87 else 88 { 89 hashed[que[i]]=change(hashed[que[i]],nexted[i]); 90 } 91 } 92 else if(hashed[que[i]]) 93 hashed[que[i]]=change(hashed[que[i]],nexted[i]); 94 else 95 { 96 t=pop(); 97 hashed[t]=0; 98 hashed[que[i]]=add(que[i],nexted[i]); 99 ans++; 100 } 101 102 } 103 printf("%d\n",ans+all); 104 } 105 return 0; 106 }
题目描述
众所周知,汀老师是XDUACM实验室最优秀的人,无论是学习还是打游戏。今天他突然想到一个好玩的游戏。规则是这样的,在游戏中他要得到n个小国,初始的时候小国和小杰各有1个。经过了很久的修炼,汀老师学会了两种魔法,他每次可以动用自己的智慧来使用魔法。
第一个魔法:(小杰变小国)可以将自己的智慧复制和当前小杰一样数量的小国出来;
第二个魔法:(小国大爆发)可以将当前的小杰变成和小国的数量一样,然后小国的数量加倍!
因为汀老师的智力是无限多的,他不关心花掉的智力大小。但是好学的汀老师想尽快得到n个小国,使得能有更多的时间去读paper和打比赛。他想问问你,最少需要使用多少次魔法可以得到n个小国。
得到了n个小国后,汀老师去学习,但是小国们基因突变在电脑里越来越多!他们来组织汀老师学习,现在告诉汀老师我要得到更多的同伴!
输入描述:
多组数据,第一行一个正整数T(T<=100000)表示数据组数。
接下来T行,每行一个正整数n(n<=10^6)。
输出描述:
对于每组数据输出一个整数,表示得到n个小国汀老师最少需要使用多少次膜法。
输入
2 1 3
输出
0 2
贼生气。。没说刚好要n个。。让我找了好久错没想到是要刚好n个。
你在纸上写几个结果看看。你可以发现如果一个数t是另一个数t*p的质数p倍的话,那么它的答案为(p-1)倍。那我们可以想到最优策略,先把原来的数t翻倍,然后+(p-2)次t。这样就p倍了。因此我们把p拆成质数连乘,然后答案就是每个质数(p-1)的和。我们可以通过线性筛快速求100w个。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<bits/stdc++.h> 2 #define clr(x) memset(x,0,sizeof(x)) 3 using namespace std; 4 const int N=1e6+10; 5 int inf[N]; 6 int eu[N]; 7 int prime[N]; 8 int tot; 9 void done(int n) 10 { 11 clr(prime); 12 clr(inf); 13 tot=0; 14 for(int i=2;i<=n;i++) 15 { 16 if(!inf[i]) 17 { 18 prime[tot++]=i; 19 inf[i]=1; 20 eu[i]=i-1; 21 } 22 for(int j=0;j<tot;j++) 23 { 24 if(prime[j]>n/i) break; 25 inf[i*prime[j]]=1; 26 if(i%prime[j]==0) 27 { 28 eu[i*prime[j]]=eu[i]+(prime[j]-1); 29 break; 30 } 31 else 32 eu[i*prime[j]]=eu[i]+(prime[j]-1); 33 } 34 } 35 return ; 36 } 37 int main() 38 { 39 int n,m; 40 done((int)1e6); 41 scanf("%d",&n); 42 for(int i=1;i<=n;i++) 43 { 44 scanf("%d",&m); 45 printf("%d\n",eu[m]); 46 } 47 return 0; 48 }
题目描述
假设有n家公司共用Tr0y的第三方服务器,各公司初始最大承受带宽为xi Gbps,当其受到大于或等于最大承受带宽流量时,会判断为DDoS攻击并进行清洗操作,将流量引到第三方服务器。
下面有Q次攻击,每次使得[Li,Ri]的公司遭受到流量为c Gbps(c为整数,在[1,C]上离散均匀分布)的攻击,且每家公司在承受攻击后会增大qi Gbps的最大承受带宽。
Tr0y的资金有限,他想知道每次攻击时,他的服务器期望承受流量为多少?
答案应该会很大,请膜1e9+7。
输入描述:
第一行为三个整数n(1<=n<=1e5),C(1e7<=C<=1e9),Q(1<=n<=1e5)。
第二行含n个整数xi(1<=xi<=10)。
接下来Q行,每行包含三个整数L,R(1<=L<=R<=n),q(1<=q<=10).
输出描述:
共Q行,每行输出服务器期望承受流量.
输入
3 10000000 3 1 2 3 1 1 1 1 2 1 1 3 1
输出
505000004 581428605 86428702
这题每次操作相互独立。因此我们算每次操作的期望就好了。
划重点,注意数据范围!你会发觉Xi+ΣQj永远小于C,这点至关重要。
假如我们当前处理的公司流量为a1~ai,我们对每个c值,他被选中的概率是1/C。对于每个$a_i$能引流的是大于等于$a_i$那部分的c值,引流量为c。因此我们的答案就是
$ \sum^r_{i=l} \ \frac{\sum^{C}_{t=a_i} \ t}{C} $
我们把这个式子拆开,我们会发现式子变成了
$\frac{(r-l+1)(c^2+c)+\sum^{r}_{i=l} \ a_i-\sum^{r}_{i=l} \ a_i^2}{2C} $
那么我们要维护的东西就显而易见了,一个是区间和,一个是区间平方和。
因此我们建立线段树维护这两个值,然后求2C的逆元,就可以在每次读入一个$q_i$后logn直接得出答案,并logn更新区间。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<bits/stdc++.h> 2 #define clr(x) memset(x,0,sizeof(x)) 3 #define LL long long 4 #define INF 0x3f3f3f3f 5 #define mod 1000000007 6 using namespace std; 7 const int N=1e5+10; 8 int n,q,l,r,qi; 9 int x[N]; 10 LL c,t; 11 struct node{ 12 int l,r; 13 LL sum,pfsum,tag; 14 }tree[N<<2]; 15 void pushdown(int i) 16 { 17 if(tree[i].tag) 18 { 19 if(tree[i].l!=tree[i].r) 20 { 21 tree[i<<1].tag=(tree[i<<1].tag+tree[i].tag)%mod; 22 tree[i<<1].pfsum=(tree[i<<1].pfsum+2*tree[i<<1].sum%mod*tree[i].tag%mod+(tree[i<<1].r-tree[i<<1].l+1)*tree[i].tag%mod*tree[i].tag%mod)%mod; 23 tree[i<<1].sum=(tree[i<<1].sum+tree[i].tag*(tree[i<<1].r-tree[i<<1].l+1)%mod)%mod; 24 tree[i<<1|1].tag=(tree[i<<1|1].tag+tree[i].tag)%mod; 25 tree[i<<1|1].pfsum=(tree[i<<1|1].pfsum+2*tree[i<<1|1].sum%mod*tree[i].tag%mod+(tree[i<<1|1].r-tree[i<<1|1].l+1)*tree[i].tag%mod*tree[i].tag%mod)%mod; 26 tree[i<<1|1].sum=(tree[i<<1|1].sum+tree[i].tag*(tree[i<<1|1].r-tree[i<<1|1].l+1)%mod)%mod; } 27 tree[i].tag=0; 28 } 29 return ; 30 } 31 void pushup(int i) 32 { 33 tree[i].sum=(tree[i<<1].sum+tree[i<<1|1].sum)%mod; 34 tree[i].pfsum=(tree[i<<1].pfsum+tree[i<<1|1].pfsum)%mod; 35 return ; 36 } 37 void init(int i,int l,int r) 38 { 39 tree[i]=(node){l,r}; 40 if(l==r) 41 { 42 tree[i].sum=x[l]; 43 tree[i].pfsum=((LL)x[l]*x[l])%mod; 44 return; 45 } 46 int mid=(l+r)>>1; 47 init(i<<1,l,mid); 48 init(i<<1|1,mid+1,r); 49 pushup(i); 50 return ; 51 } 52 void update(int i,int l,int r,int val) 53 { 54 if(tree[i].l>=l && tree[i].r<=r) 55 { 56 tree[i].tag=(tree[i].tag+val)%mod; 57 tree[i].pfsum=(tree[i].pfsum+2*tree[i].sum%mod*val%mod+(tree[i].r-tree[i].l+1)*val%mod*val%mod)%mod; 58 tree[i].sum=(tree[i].sum+val*(tree[i].r-tree[i].l+1)%mod)%mod; 59 return ; 60 } 61 pushdown(i); 62 int mid=(tree[i].l+tree[i].r)>>1; 63 if(mid>=l) 64 update(i<<1,l,r,val); 65 if(mid<r) 66 update(i<<1|1,l,r,val); 67 pushup(i); 68 return ; 69 } 70 LL query(int i,int l,int r) 71 { 72 if(tree[i].l>=l && tree[i].r<=r) 73 return ((tree[i].sum-tree[i].pfsum)%mod+mod)%mod; 74 pushdown(i); 75 int mid=(tree[i].l+tree[i].r)>>1; 76 if(mid<l) 77 return query(i<<1|1,l,r); 78 else if(mid>=r) 79 return query(i<<1,l,r); 80 else return (query(i<<1,l,r)+query(i<<1|1,l,r))%mod; 81 } 82 LL quickpow(LL x,LL n) 83 { 84 LL ans=1; 85 x=x%mod; 86 while(n) 87 { 88 if(n&1) 89 ans=ans*x%mod; 90 n>>=1; 91 x=x*x%mod; 92 } 93 return ans; 94 } 95 LL ans,dc; 96 int main() 97 { 98 scanf("%d%lld%d",&n,&c,&q); 99 for(int i=1;i<=n;i++) 100 scanf("%d",x+i); 101 init(1,1,n); 102 dc=quickpow(2*c,mod-2); 103 for(int i=1;i<=q;i++) 104 { 105 scanf("%d%d%d",&l,&r,&qi); 106 printf("%lld\n",(query(1,l,r)+(r-l+1)*(c*c%mod+c)%mod)%mod*dc%mod); 107 update(1,l,r,qi); 108 } 109 return 0; 110 }