连接:http://codeforces.com/contest/1062c++
题意:数组
给出长度为 $n(1 \le n \le 100)$ 的数组 $a[1 \sim n]$,且知足 $1 \le a[1] < a[2] < \cdots < a[n] \le 1000$。如今JATC要擦掉其中一段连续的数字,可是要求可以经过剩余的其余数字,推断出擦掉的数字是什么。求JATC能擦掉的最长长度。spa
题解:code
其实 $O(n)$ 就能够求出能擦掉的最长长度,可是由于 $n$ 比较小,懒得考虑太多,直接二分吧……blog
二分能擦掉的长度,对于固定的长度,$O(n)$ 枚举始末点判断可否擦除便可。ci
AC代码:get
#include<bits/stdc++.h> using namespace std; const int maxn=105; int n,a[maxn]; bool judge(int k) { for(int i=1,j=i+k-1;j<=n;i++,j++) { if(a[j+1]-a[i-1]==k+1) return 1; } return 0; } int main() { cin>>n; for(int i=1;i<=n;i++) cin>>a[i]; a[0]=0, a[n+1]=1001; int l=0, r=n; while(l<r) { int mid=(l+r+1)/2; if(judge(mid)) l=mid; else r=mid-1; } cout<<l<<endl; }
题意:数学
给出一个正整数 $n(1 \le n \le 1e6)$,你如今能够对 $n$ 进行任意屡次乘以正整数 $x$ 或者开方(当结果为整数时才容许开方)操做。it
求结果最小为多少,达到这个结果最少进行多少次操做。class
题解:
分解质因数 $n = {p_1}^{a_1}{p_2}^{a_2} \cdots {p_k}^{a_k}$,显然最后结果只能是 $p_1 p_2 \cdots p_k$,那么如何才能获得 $p_1 p_2 \cdots p_k$?
找到 $\max(a_i)$,求得比小于它的最小 $2^x$,这样一来先作一次乘法把 $n$ 乘到 ${p_1}^{2^x}{p_2}^{2^x} \cdots {p_k}^{2^x}$,而后作 $2^x$ 次开方操做便可获得 $p_1 p_2 \cdots p_k$。所以最少 $x+1$ 次操做。
(固然,还有一些数字自己就是最小结果,这些另做判断便可。)
AC代码:
#include<bits/stdc++.h> using namespace std; int n; pair<int,int> solve(int n) { if(n<=1) return make_pair(n,0); int res=1,mx=0, mn=20; for(int i=2;i*i<=n;i++) { if(n%i==0) { res*=i; int cnt=0; while(n%i==0) n/=i, cnt++; mx=max(cnt,mx); mn=min(cnt,mn); } } if(n>1) res*=n, mx=max(1,mx), mn=min(1,mn); int t=ceil(log2(mx))+1e-8; if(mn==mx && (1<<t)==mx) return make_pair(res,t); else return make_pair(res,t+1); } int main() { while(cin>>n) { pair<int,int> ans=solve(n); cout<<ans.first<<' '<<ans.second<<endl; } }
题意:
有一个食物,将其分红 $n(1 \le n \le 1e5)$ 份,编号为 $1 \sim n$,第 $i$ 份食物的初始美味度为 $x_i(x_i \in {0,1})$,
如今有 $q(1 \le q \le 1e5)$ 次查询,每一个查询 $[l,r]$ 表明如今只考虑该区间内的食物,每次我吃其中的某一份食物 $i$,个人喜悦程度就会加上 $x_i$,同时区间内全部其余剩余的食物的 $x_j$ 都会加上 $x_i$。
如今要求对每一个查询,输出我最大能得到的喜悦程度。
题解:
首先确定是贪心地吃食物,每次都吃 $x_i$ 最大的食物。
假设初始区间内有 $a$ 个 $1$,$b$ 个 $0$,那么先吃完全部初始美味度为 $1$ 的食物,获得喜悦程度为
$1 + 2 + 4 + \cdots + 2^{a-1} = 2^0 + 2^1 + 2^2 + \cdots + 2^{a-1} = 2^a - 1$
接下来,剩下的初始美味度为 $0$ 的食物,如今美味度都变成了 $2^a - 1$,吃完这些食物获得喜悦程度为
$(2^a - 1) \cdot 2^0 + (2^a - 1) \cdot 2^1 + \cdots + (2^a - 1) \cdot 2^{b-1} = (2^a - 1)(2^0 + 2^1 + \cdots + 2^{b-1}) = (2^a - 1)(2^b - 1)$
所以我只须要经过前缀和,就能 $O(1)$ 统计出任意区间内 $0$ 和 $1$ 的数目,而后只须要快速幂求出 $2^a - 1 + (2^a - 1)(2^b - 1) = (2^a - 1)2^b$ 便可。
AC代码:
#include<bits/stdc++.h> using namespace std; typedef long long ll; const ll mod=1e9+7; const int maxn=1e5+10; int n,q; char s[maxn]; int c[2][maxn]; ll fpow(ll a,ll n) { ll res=1,base=a%mod; while(n) { if(n&1) res*=base, res%=mod; base*=base, base%=mod; n>>=1; } return res%mod; } int main() { scanf("%d%d",&n,&q); scanf("%s",s+1); c[0][0]=c[1][0]=0; for(int i=1,x;i<=n;i++) { x=s[i]-'0'; c[x][i]=c[x][i-1]+1; c[x^1][i]=c[x^1][i-1]; } for(int i=1,l,r;i<=q;i++) { scanf("%d%d",&l,&r); ll a=c[1][r]-c[1][l-1], b=c[0][r]-c[0][l-1]; printf("%lld\n",(fpow(2,a+b)-fpow(2,b)+mod)%mod); } }