存一下训练赛的代码
A. 二分1
题源-洛谷P2249
AC代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e6+5;
int a[N];
int main() {
::sync_with_stdio(false);
iosint n,m;
>>n>>m;
cinfor(int i=1;i<=n;i++)
>>a[i];
cinwhile(m--)
{
int q;
>>q;
cinint pos=lower_bound(a+1,a+1+n,q)-a;
if(a[pos]==q)
<<pos<<' ';
coutelse
<<-1<<' ';
cout}
return 0;
}
B. 前缀和差分1
题源-洛谷-P8218
AC代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e5+5;
int a[N];
[N];
ll sumint main() {
::sync_with_stdio(false);
iosint n;
>>n;
cinfor(int i=1;i<=n;i++)
{
>>a[i];
cin[i]=a[i]+sum[i-1];
sum}
int m;
>>m;
cinfor(int i=1;i<=m;i++)
{
int l,r;
>>l>>r;
cin<<sum[r]-sum[l-1]<<'\n';
cout}
return 0;
}
C. 素数1
题源-洛谷-P1835
直接筛肯定会超,所以缩小范围,筛
AC代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e6+5;
<ll>p;
vectorbool vis[N];
int main() {
::sync_with_stdio(false);
ios,R;
ll L>>L>>R;
cinfor(int i=2;i<N;i++)
{
if(!vis[i])
{
.push_back(i);
pfor(int j=2;j*i<N;j++)
[j*i]=true;
vis}
}
if(L==1)
+=1;
Lif(L>R)
<<0<<'\n';
coutelse
{
(vis,false,sizeof(vis));
memsetfor(auto p:p)
{
for(int j=max(2ll,L/p);j*p<=R;j++)
{
if(j*p>=L)
[j*p-L]=true;
vis}
}
=0;
ll cntfor(int i=0;i<=R-L;i++)
if(!vis[i])
++;
cnt<<cnt<<'\n';
cout}
return 0;
}
D. dfs1
题源-洛谷-P1025
可以dp,
如果
如果
如果
将上面两种情况加起来就是结果,即
AC代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=205;
int dp[N][10];
int main() {
::sync_with_stdio(false);
iosint n,k;
>>n>>k;
cinfor(int i=1;i<=n;i++)
[i][1]=dp[i][0]=1;
dpfor(int j=2;j<=k;j++)
{
for(int i=2;i<=n;i++)
{
if(i>j)
[i][j]=dp[i-1][j-1]+dp[i-j][j];
dpelse
[i][j]=dp[i-1][j-1];
dp}
}
<<dp[n][k]<<'\n';
coutreturn 0;
}
E. 杂题1
题源-CodeForces - 1771A
题目统计的是差的绝对值最大的数对,可以统计最大值和最小值的个数,然后乘起来再乘二就是结果
需要注意的是最大值和最小值可能相同,这个时候整个序列每个数都相同,这时候数对中的元素无法交换,不能乘2
AC代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e5+5;
int a[N];
int main() {
::sync_with_stdio(false);
iosint T;
>>T;
cinwhile(T--)
{
;
ll n>>n;
cinfor(int i=1;i<=n;i++)
{
>>a[i];
cin}
int m=min_element(a+1,a+1+n)-a;
int M=max_element(a+1,a+1+n)-a;
=0,y=0;
ll xfor(int i=1;i<=n;i++)
{
if(a[i]==a[m])
++;
xif(a[i]==a[M])
++;
y}
if(a[m]==a[M])
<<x*y-n<<'\n';
coutelse
<<x*y*2<<'\n';
cout}
return 0;
}
F. 二分2
题源-洛谷 - P2440
经典模板题
AC代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e5+5;
[N];
ll L,k;
ll nbool judge(ll x)
{
=0;
ll cntfor(int i=1;i<=n;i++)
+=L[i]/x;
cntreturn cnt>=k;
}
int main() {
::sync_with_stdio(false);
ios>>n>>k;
cin=0;
ll Mfor(int i=1;i<=n;i++)
{
>>L[i];
cin=max(M,L[i]);
M}
=2,right=M;
ll leftif(!judge(1))
<<0<<'\n';
coutelse
{
=1;
ll answhile(left<right)
{
=(left+right)>>1;
ll midif(judge(mid))
{
=mid+1;
left=mid;
ans}
else
=mid;
right}
<<ans<<'\n';
cout}
return 0;
}
G. 前缀和差分2
题源-洛谷 - P2367
只用最后一次查询最小值,可以用差分优化修改
AC代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=5e6+5;
int a[N];
int d[N];
int main() {
::sync_with_stdio(false);
iosint n,p;
>>n>>p;
cin[0]=0;
afor(int i=1;i<=n;i++)
{
>>a[i];
cin[i]=a[i]-a[i-1];
d}
while(p--)
{
int x,y,z;
>>x>>y>>z;
cin[x]+=z;
d[y+1]-=z;
d}
for(int i=1;i<=n;i++)
[i]=a[i-1]+d[i];
aint pos=min_element(a+1,a+1+n)-a;
<<a[pos]<<'\n';
coutreturn 0;
}
H. 二分3
题源-洛谷 - P2678
AC代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=5e4+5;
int d[N];
int L,n,m;
bool judge(int x)
{
int cur=0,cnt=0;
for(int i=1;i<=n+1;i++)
{
if(d[i]-d[cur]<x)
++;
cntelse
=i;
cur}
if(cnt>m)
return false;
return true;
}
int main() {
::sync_with_stdio(false);
ios>>L>>n>>m;
cin[0]=0;
dfor(int i=1;i<=n;i++)
>>d[i];
cin[n+1]=L;
dif(n==0)
<<L<<'\n';
coutelse
{
int left=0,right=L;
int ans=0;
while(left<right)
{
int mid=(left+right)>>1;
if(judge(mid))
{
=mid+1;
left=mid;
ans}
else
=mid;
right}
<<ans<<'\n';
cout}
return 0;
}
dfs2
题源-洛谷 - P1434
直接dfs复杂度会炸,于是用记忆化搜索优化
AC代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=105;
int h[N][N],s[N][N];
int dx[4]={-1,0,1,0},dy[4]={0,1,0,-1};
int length;
int ans;
int R,C;
void dfs(int x,int y)
{
if(x<1||x>R||y<1||y>C)
return;
if(s[x][y]!=0)
{
+=s[x][y];
length=max(ans,length);
ans-=s[x][y];
lengthreturn;
}
++;
length=max(ans,length);
ansfor(int i=0;i<4;i++)
{
int x_now=x+dx[i],y_now=y+dy[i];
if(h[x_now][y_now]<h[x][y])
(x_now,y_now);
dfs}
--;
length}
int main() {
::sync_with_stdio(false);
ios
>>R>>C;
cinfor(int i=1;i<=R;i++)
{
for(int j=1;j<=C;j++)
>>h[i][j];
cin}
for(int i=1;i<=R;i++)
{
for(int j=1;j<=C;j++)
{
=0;
length=0;
ans(i,j);
dfs[i][j]=ans;
s}
}
int M=0;
for(int i=1;i<=R;i++)
{
for(int j=1;j<=C;j++)
=max(M,s[i][j]);
M}
<<M<<'\n';
coutreturn 0;
}
K. 前缀和差分3
题源-洛谷 - P2368
111111111
119357639
380642361
388888889
611111111
619357639
880642361
888888889
显然如果更高位数的平方后9位是987654321,那么这个更高位数的后9位也得是这些里面的一个、
于是答案就显然了
AC代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int main() {
::sync_with_stdio(false);
ios// for(ll i=100000000;i<=999999999;i++)
// {
// if(i*i%1000000000==987654321)
// cout<<i<<'\n';
// }
int n;
>>n;
cinif(n<9)
<<0<<'\n';
coutelse if(n==9)
<<8<<'\n';
coutelse if(n==10)
<<72<<'\n';
coutelse
{
<<72;
coutfor(int i=1;i<=n-10;i++)
<<0;
cout<<'\n';
cout}
return 0;
}