/*
容斥原理
考虑到a[i]要么不会太大,要么就对答案贡献很小
dfs即可
*/
#include<bits/stdc++.h> #define ll long long
#define rep(i,a,n) for(int i=a;i<=n;i++) using namespace std; ll read()
{
ll ans=;
char last=' ',ch=getchar();
while(ch<'' || ch>'')last=ch,ch=getchar();
while(ch>='' && ch<='')ans=ans*+ch-'',ch=getchar();
if(last=='-')ans=-ans;
return ans;
} ll gcd(ll a,ll b){return (!b)?a:gcd(b,a%b);} ll ans=;
int n,m,a[];
ll Gcd(ll a,ll b)
{
if(!b)return a;
return gcd(b,a%b);
}
void dfs(int dep,ll t,int flag)
{
if(t>n)return;
if(dep==m+)
{
ans+=n/t*flag;
return;
}
dfs(dep+,t,flag);
dfs(dep+,t/Gcd(t,a[dep])*a[dep],-flag);
}
int main()
{
freopen("count.in","r",stdin);
freopen("count.out","w",stdout);
n=read();
m=read();
rep(i,,m)a[i]=read();
dfs(,,);
cout<<ans<<endl;
return ;
}

#include<bits/stdc++.h>

#define N 20000007

using namespace std;
int n,k,num,cnt,ans,mx,mn;
int a[N],k_th[N]; inline int read()
{
int x=,f=;char c=getchar();
while(c>''||c<''){if(c=='-')f=-;c=getchar();}
while(c>=''&&c<=''){x=x*+c-'';c=getchar();}
return x*f;
} inline bool cmp(int a,int b)
{
return a>b;
} int main()
{
freopen("kth.in","r",stdin);
freopen("kth.out","w",stdout);
n=read();k=read();
for(int i=;i<=n;i++)a[i]=read();
for(int i=;i<=n;i++)
{
mx=mn=a[i];
for(int j=i+;j<=n;j++)
{
if(a[j]>mx) mx=a[j];
if(a[j]<mn) mn=a[j];
k_th[++cnt]=mx-mn;
}
}
sort(k_th+,k_th+cnt+,cmp);
printf("%d\n",k_th[k]);
return ;
}

30暴力

/*
二分+单调队列
可以看出对于一个区间[L,R],[L-1,R]的价值一定不比他小
所以答案可以二分,然后判断是否这个答案是第k大
可以用单调队列维护最大最小值,对于每一个右端点,
找距离它最近的左端点满足这个区间的价值<=k,那么这个左端点往左都是比当前二分出答案大的。
复杂度 O(nlogn)
*/
#include<iostream>
#include<cstdio>
#include<cstring> #define N 410007
#define ll long long using namespace std;
ll n,m,k,ans,cnt;
ll a[N],q1[N],q2[N]; inline ll read()
{
ll x=,f=;char c=getchar();
while(c>''||c<''){if(c=='-')f=-;c=getchar();}
while(c>=''&&c<=''){x=x*+c-'';c=getchar();}
return x*f;
} bool judge(int x)
{
int l=,r=,L=,R=;
ll res=;q1[]=,q2[]=;
int Left=;
if(x==) res=;else res=;
for(int i=;i<=n;i++)
{
while(l<=r && a[i]<=a[q1[r]]) --r;
q1[++r]=i;
while(L<=R && a[i]>=a[q2[R]]) --R;
q2[++R]=i; while(Left<i)
{
int tmp1=l,tmp2=L;Left++;
while(q1[tmp1]<Left) tmp1++;
while(q2[tmp2]<Left) tmp2++;
if(a[q2[tmp2]]-a[q1[tmp1]]>=x) l=tmp1,L=tmp2;
else {Left--;break;}
}
if(a[q2[L]]-a[q1[l]]>=x) res+=Left;
}
return res>=k;
} int main()
{
freopen("kth.in","r",stdin);
freopen("kth.out","w",stdout);
int x,y;
n=read();k=read();
for(int i=;i<=n;i++) a[i]=read();
int l_=,r_=;
while(l_<=r_)
{
int mid=(l_+r_)>>;
if(judge(mid))ans=mid,l_=mid+;
else r_=mid-;
}
cout<<ans<<endl;
return ;
}

/*
特别好的思路
考虑如果选定了几个武器要求这些武器都不被摧毁,判断是否可能
从左到右判断,需要无后效性,所以显然要按攻击力从小到大放
那么每放入一个选定的武器后在其后面添加r个比他攻击力小的武器
若当前找不出r个比它攻击力小的武器则判断失败
以上判断有个简单的表示方式:攻击力第i小的选定武器其攻击力在所有武器中的排名需
要>=i*(r+1)
状态很巧妙 dp[i][j]表示前j个武器选了i个且判定合法的战场贡献最大值
转移的时候判断第j个选不选即可
*/
#include<bits/stdc++.h> #define N 5007
#define inf 0x3f3f3f3f using namespace std;
int n,m,r,ans,cnt;
int dp[N][N];
struct node{
int f,w;
bool operator < (const node &a) const{
return f<a.f;
}
}p[N]; inline int read()
{
int x=,f=;char c=getchar();
while(c>''||c<''){if(c=='-')f=-;c=getchar();}
while(c>=''&&c<=''){x=x*+c-'';c=getchar();}
return x*f;
} int main()
{
freopen("submax.in","r",stdin);
freopen("submax.out","w",stdout);
int T;T=read();
while(T--)
{
n=read();r=read();
for(int i=;i<=n;i++) p[i].f=read();
for(int i=;i<=n;i++) p[i].w=read();
sort(p+,p+n+);
m=n/(r+)+;ans=;
memset(dp,,sizeof dp);
for(int i=;i<=m;i++)
{
int R=min(n,i*(r+));
for(int j=;j<=R-;j++) dp[i][j]=-inf;
for(int j=R;j<=n;j++)
dp[i][j]=max(dp[i][j-],dp[i-][j-]+p[j].w);
ans=max(ans,dp[i][n]);
}
printf("%d\n",ans);
}
return ;
}
p noip 提高组模拟赛 day1
.计数
(count.cpp/c/pas)
.计数
(count.cpp/c/pas)
时间限制:1s
内存限制:256MB
【问题描述】
给出 m 个数 a[],a[],…,a[m]
求 ~n 中有多少数不是 a[],a[],…,a[m]的倍数。
【输入】
输入文件名为 count.in。
第一行,包含两个整数:n,m
第二行,包含 m 个数,表示a[],a[],…,a[m]
【输出】
输出文件名为 count.out。
输出一行,包含 个整数,表示答案
【输入输出样例】
count.in count.out 【数据说明】
对于 %的数据,<=n<= 对于另外 %的数据,m=
对于 %的数据,<=n<=
,<m<=,<=a[i]<=
更多资 询 :北京信息学窦老师 QQ3377089232
.区间第 k 大
(kth.cpp/c/pas)
.区间第 k 大
(kth.cpp/c/pas)
时间限制:1s
内存限制:256MB
【问题描述】
一个区间的价值定义为该区间中的最大值减最小值
给定 n 个数,求所有区间价值中,第 k 大值为多少。
【输入】
输入文件名为 kth.in。
第 行两个数 n、k(k<=n*(n-)/)
第 行 n 个数,每个数<= 【输出】
输出文件名为 kth.out。
输出区间价值的第 k 大值。
【输入输出样例】
kth.in kth.out 【样例解释】
[l,r]表示第 l 个数到第 r 个数组成的区间的价值
[,]= [,]= [,]=
[,]= [,]=
[,]=
【数据说明】
对于 %的数据,n=
对于 %的数据,n<=
对于 %的数据,n<=
更多资 询 :北京信息学窦老师 QQ3377089232
.武器分配
(submax.cpp/c/pas)
.武器分配
(submax.cpp/c/pas)
时间限制:1s
内存限制:256MB
【问题描述】
有 n 个堡垒排成一排构成了一条防御线。 现在需要将 n 个武器放入这 n 个堡垒中, 每个
堡垒放一个,每个武器有攻击力和战场贡献值两个属性。
由于这 n 个武器都不是人为操控的, 所以会对其某半径内所有单位进行攻击, 而这就导
致某些堡垒的互相攻击。现在发现第 i 个堡垒会和第 j 个堡垒互相攻击当且仅当|i-j|<=r,
且攻击力较低的武器和他所在的堡垒会破损。
现在你需要给出一种武器分配方案使得未破损武器的战场贡献值总和最大。 为了方便你
只需输出战场贡献值总和的最大值即可。
【输入】
输入文件名为submax.in。
第一行一个数 T(<=),表示数据组数
对于每一组数据:
第一行两个数 n,r
第二行 n 个数,表示 ~n 号武器的攻击力
第三行 n 个数,表示 ~n 号武器的战场贡献值
【输出】
输出文件名为submax.out。
对于每组数据输出一个数,表示答案
【输入输出样例】
submax.in submax.out 【数据范围】
对于 %的数据:n<=
对于 %的数据,n<=
对于 %的数据,n<=,武器攻击力<= 且两两不同,武器的战场贡献值
<=,r<n
更多资 询 :北京信息学窦老师 QQ3377089232

题面

最新文章

  1. UE4新手之编程指南
  2. Git 常用命令
  3. 关于 IIS 中 Excel 访问的问题
  4. 一个基于Orchard的开源CRM --coevery简介
  5. BFC之宽度自适应布局篇
  6. jpa遇到的 org.hibernate.PersistentObjectException: detached entity passed to persist异常
  7. iptables之链之间的跳转
  8. Comparing the Performance of .NET Serializers(zz)
  9. javascript encode或者decode html
  10. Java学习笔记之:Java 接口
  11. Android自定义TTF字体
  12. sublime Text2.0.2注册码
  13. Python新手学习基础之运算符——成员运算与身份运算
  14. 窗口!窗口!- Windows程序设计(SDK)003
  15. MYSQL获取自增主键【4种方法】
  16. ASP.NET CORE的Code Fist后Models更改了怎么办?
  17. Spring+MVC Controller层接收App端请求的中文参数乱码问题。
  18. Java 利用 UUID 生成唯一性 ID 示例代码
  19. Awesome-VR
  20. 使用WebBrowser控件播放Flash网页相关问题解决方法(转)

热门文章

  1. github some rank
  2. Dijkstra算法C++实现总结
  3. 完美解决了span的宽度设置
  4. ORACLE数据库查看执行计划的方法
  5. 【KMP+最小循环节】F. Cyclic Nacklace
  6. Linux中kill,pkill,killall和xkill命令汇总讲解
  7. 洛谷 P1183 多边形的面积
  8. LENOVO System x3850 X6
  9. jquery校验框架
  10. js获取上传的文件名称