Codeforces Round #510 (Div. 2)

https://codeforces.com/contest/1042

A

二分

 #include<iostream>
using namespace std;
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
#define sqr(x) ((x)*(x))
#define pb push_back
#define eb emplace_back
#define maxn 100005
#define eps 1e-8
#define pi acos(-1.0)
#define rep(k,i,j) for(int k=i;k<j;k++)
typedef long long ll;
typedef pair<int,int> pii;
typedef pair<double,double>pdd;
typedef pair<int,char> pic;
typedef pair<pair<int,string>,pii> ppp;
typedef unsigned long long ull;
const long long MOD=;
const double oula=0.57721566490153286060651209;
using namespace std; int n;
int a[];
int m; bool Check(int mid,int x){
for(int i=;i<=n;i++){
x-=mid-a[i];
}
if(x>) return true;
return false;
} int main(){
std::ios::sync_with_stdio(false);
cin>>n>>m;
int Max=;
for(int i=;i<=n;i++){
cin>>a[i];
Max=max(Max,a[i]);
}
int ans2=Max+m;
int L=Max,R=ans2,mid;
while(L<=R){
mid=L+R>>;
if(Check(mid,m)){
L=mid+;
}
else{
R=mid-;
}
}
cout<<L<<" "<<ans2<<endl;
}

B

暴力模拟

 #include<bits/stdc++.h>
using namespace std;
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
#define sqr(x) ((x)*(x))
#define pb push_back
#define eb emplace_back
#define maxn 100005
#define eps 1e-8
#define pi acos(-1.0)
#define rep(k,i,j) for(int k=i;k<j;k++)
typedef long long ll;
typedef pair<int,int> pii;
typedef pair<double,double>pdd;
typedef pair<int,char> pic;
typedef pair<pair<int,string>,pii> ppp;
typedef unsigned long long ull;
const long long MOD=;
const double oula=0.57721566490153286060651209;
using namespace std; int n;
struct sair{
int v;
string s;
}a[]; map<string,int>mp; int main(){
std::ios::sync_with_stdio(false);
cin>>n;
int flag=;
mp["A"]=;
mp["B"]=;
mp["C"]=;
mp["AB"]=;
mp["AC"]=;
mp["BC"]=;
mp["ABC"]=;
for(int i=;i<=n;i++){
cin>>a[i].v>>a[i].s;
for(int j=;j<a[i].s.length();j++){
flag|=(<<(a[i].s[j]-'A'));
}
sort(a[i].s.begin(),a[i].s.end());
if(mp[a[i].s]>a[i].v) mp[a[i].s]=a[i].v;
}
if(flag!=){
cout<<-<<endl;
}
else{
int ans=0x3f3f3f3f;
ans=min(ans,min(mp["A"]+mp["B"]+mp["C"],min(mp["AB"]+mp["BC"],min(mp["AC"]+mp["BC"],min(mp["AB"]+mp["AC"],min(mp["ABC"],min(mp["A"]+mp["BC"],min(mp["B"]+mp["AC"],mp["C"]+mp["AB"]))))))));
cout<<ans<<endl;
} }

C

题意:给n个数,每次使a[j]=a[i]*a[j],a[i]删除,使最后的数值最大。最多可以直接删除一个数字

思路:模拟。把正数,负数,零分别记录下标。如果负数的个数为偶数,就把它放到存放正数的vector里,否则取出一个最大的,把剩下的放到正数的vecotr里,然后把0和负数相乘后删除或直接删除负数,最后把正数相乘即可(打完才发现这是半年前遗留下来的题。。。)

 #include<bits/stdc++.h>
using namespace std;
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
#define sqr(x) ((x)*(x))
#define pb push_back
#define eb emplace_back
#define maxn 100005
#define eps 1e-8
#define pi acos(-1.0)
#define rep(k,i,j) for(int k=i;k<j;k++)
typedef long long ll;
typedef pair<int,int> pii;
typedef pair<double,double>pdd;
typedef pair<int,char> pic;
typedef pair<pair<int,string>,pii> ppp;
typedef unsigned long long ull;
const long long MOD=;
const double oula=0.57721566490153286060651209;
using namespace std; ll n;
ll a[];
vector<int>z;
vector<int>f;
vector<int>zero;
int ff=-,zz=-,ze=-;
int main(){
std::ios::sync_with_stdio(false);
cin>>n;
for(int i=;i<=n;i++){
cin>>a[i];
if(a[i]==) zero.pb(i);
else if(a[i]>) z.pb(i);
else f.pb(i);
}
if(f.size()%){
int pos=,Max=-0x3f3f3f3f;
for(int i=;i<f.size();i++){
if(a[f[i]]>Max){
Max=a[f[i]];
pos=i;
}
}
ff=f[pos];
f[pos]=-;
for(int i=;i<f.size();i++){
if(f[i]!=-){
z.pb(f[i]);
}
}
f.clear();
}
else{
for(int i=;i<f.size();i++){
z.pb(f[i]);
}
f.clear();
}
if(f.size()>=) ff=f[];
for(int i=;i<f.size();i++){
cout<<<<" "<<f[i]<<" "<<ff<<endl;
}
if(zero.size()>=) ze=zero[];
for(int i=;i<zero.size();i++){
cout<<<<" "<<zero[i]<<" "<<ze<<endl;
}
if(ff!=-&&ze!=-){
cout<<<<" "<<ff<<" "<<ze<<endl;///ze
}
if(z.size()>){
if(ff!=-&&ze!=-)
cout<<<<" "<<ze<<endl;
else if(ff!=-){
cout<<<<" "<<ff<<endl;
}
else if(ze!=-){
cout<<<<" "<<ze<<endl;
}
zz=z[];
for(int i=;i<z.size();i++){
cout<<<<" "<<z[i]<<" "<<zz<<endl;
}
} }

D

题意:给n个数,求一段区间和小于k

思路:看到区间和就会想到前缀和,然后可以发现一个公式:sum[r]-sum[l-1]<k  转换下 :sum[r]-k<sum[l-1]

当我们遍历右端点时,可以发现,已知sum[r],k求sum[l-1] 就容易发现,这是一道可以用权值线段树求区间个数的题目

 #include<bits/stdc++.h>
using namespace std;
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
#define sqr(x) ((x)*(x))
#define pb push_back
#define eb emplace_back
#define maxn 400005
#define eps 1e-8
#define pi acos(-1.0)
#define rep(k,i,j) for(int k=i;k<j;k++)
typedef long long ll;
typedef pair<int,int> pii;
typedef pair<double,double>pdd;
typedef pair<int,char> pic;
typedef pair<pair<int,string>,pii> ppp;
typedef unsigned long long ull;
const long long MOD=;
const double oula=0.57721566490153286060651209;
using namespace std; ll n,t;
ll a[maxn];
ll b[maxn];
vector<ll>ve;
ll tree[maxn<<]; int getid(ll x){
return lower_bound(ve.begin(),ve.end(),x)-ve.begin()+;
} void push_up(int rt){
tree[rt]=tree[rt<<]+tree[rt<<|];
} void add(int L,int l,int r,int rt){
// cout<<L<<" "<<l<<" "<<r<<" "<<tree[rt]<<endl;
if(l==r) {
tree[rt]++;
return;
}
int mid=l+r>>;
if(L<=mid) add(L,lson);
else add(L,rson);
push_up(rt);
} ll query(int L,int R,int l,int r,int rt){
// cout<<L<<" "<<R<<" "<<l<<" "<<r<<" "<<tree[rt]<<endl;
if(L<=l&&R>=r){
return tree[rt];
}
int mid=l+r>>;
ll ans=;
if(L<=mid) ans+=query(L,R,lson);
if(R>mid) ans+=query(L,R,rson);
return ans;
} int main(){
std::ios::sync_with_stdio(false);
cin>>n>>t;
t--;
ll ans=;
for(int i=;i<=n;i++){
cin>>a[i];
b[i]=b[i-]+a[i];
}
for(int i=;i<=n;i++){
ve.pb(b[i]);
ve.pb(b[i]-t);
}
ve.pb();///**************************************
sort(ve.begin(),ve.end());
ve.erase(unique(ve.begin(),ve.end()),ve.end());
int N=ve.size();
int pos;
// if(b[1]<=t) ans++;
add(getid(),,N,);
for(int i=;i<=n;i++){
pos=getid(b[i]-t);
// add(getid(b[i]),1,N,1);
ll tmp=query(pos,N,,N,);
add(getid(b[i]),,N,);
ans+=tmp;
}
cout<<ans<<endl;
}

E

DP

题意:给n*m的矩阵,给出每个位置的权值,求从出发点出发,每次可以等概率的移动到一个权值小于当前点权值的点,同时得分加上两个点之间欧几里得距离的平方,问得分的期望

思路在代码里

 #include<bits/stdc++.h>
using namespace std;
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
#define sqr(x) ((x)*(x))
#define pb push_back
#define eb emplace_back
#define maxn 1005
#define eps 1e-8
#define pi acos(-1.0)
#define rep(k,i,j) for(int k=i;k<j;k++)
typedef long long ll;
typedef pair<int,int> pii;
typedef pair<double,double>pdd;
typedef pair<int,char> pic;
typedef pair<pair<int,string>,pii> ppp;
typedef unsigned long long ull;
const long long MOD=;
const double oula=0.57721566490153286060651209;
using namespace std; ll n,m; struct sair{
int x,y,v;
}a[maxn*maxn]; bool cmp(sair a,sair b){
return a.v<b.v;
} ll dp[maxn*maxn];
ll inv[maxn*maxn];
ll sum,sumdp,sumx,sumx2,sumy,sumy2;
/**状态转移方程:dp[i]=sum(dp[j]+(x[i]-x[j])^2+(y[i]-y[j])^2)/s
展开后:dp[i]=sum(dp[j]+x[i]^2-2*x[i]x[j]+x[j]^2+y[i]^2-2*y[i]y[j]+y[j]^2)/s
令sumdp=sum(dp[j]),sumx=sum(sum[j]),sumx2=sum(sum[j]*sum[j])
sumy,sumy2同理
转换下:dp[i]=(sumf+sum*x[i]*x[i]-2*x[i]*sumx+sumx2+sum*y[i]*y[i]-2*y[i]*sumy+sumy*sumy)/s;
sum变量为比它小的个数
*/
int main(){
std::ios::sync_with_stdio(false);
cin>>n>>m;
int x,y;
for(int i=;i<=n;i++){
for(int j=;j<=m;j++){
cin>>a[(i-)*m+j].v;
a[(i-)*m+j].x=i;
a[(i-)*m+j].y=j;
}
}
cin>>x>>y;
n*=m;
sort(a+,a+n+,cmp);
inv[]=;
for(int i=;i<=n;i++) inv[i]=(-MOD/i*inv[MOD%i])%MOD;///求逆元
a[n+].v=-;
for(int i=;i<=n;i++){
if(sum){
dp[i]=((dp[i]+((sum*a[i].x*a[i].x)%MOD-*sumx*a[i].x%MOD+sumx2)%MOD)+MOD)%MOD;
dp[i]=((dp[i]+((sum*a[i].y*a[i].y)%MOD-*sumy*a[i].y%MOD+sumy2)%MOD)+MOD)%MOD;
dp[i]=(dp[i]+sumdp)%MOD;
dp[i]=dp[i]*inv[sum]%MOD;
}
else{
dp[i]=;
}
if(a[i].x==x&&a[i].y==y){
cout<<(dp[i]+MOD)%MOD<<endl;
break;
}
if(a[i].v!=a[i+].v){
for(int j=i;j;j--){
if(a[j].v!=a[i].v) break;
sumdp=(sumdp+dp[j])%MOD;
sumx=(sumx+a[j].x)%MOD;
sumx2=(sumx2+(a[j].x)*a[j].x)%MOD;
sumy=(sumy+a[j].y)%MOD;
sumy2=(sumy2+a[j].y*a[j].y)%MOD;
sum++;
}
}
}
}

F

题意:给你一棵树,求它所有叶子节点最少可以划分为多少个集合,划分的依据为集合内的叶子节点两两之间的距离不超过k

思路:这题用逆向思维。父节点存叶子节点的距离,当距离最大的两个叶子节点之和超过k时,就需要多划分一个集合

 #include<bits/stdc++.h>
using namespace std;
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
#define sqr(x) ((x)*(x))
#define pb push_back
#define eb emplace_back
#define maxn 3000006
#define eps 1e-8
#define pi acos(-1.0)
#define rep(k,i,j) for(int k=i;k<j;k++)
typedef long long ll;
typedef pair<int,int> pii;
typedef pair<double,double>pdd;
typedef pair<int,char> pic;
typedef pair<pair<int,string>,pii> ppp;
typedef unsigned long long ull;
const long long MOD=;
const double oula=0.57721566490153286060651209;
using namespace std; vector<int>ve[maxn];
bool vis[maxn];
int n,k;
int ans=; int dfs(int now){
vector<int>tmp;
vis[now]=;
if(ve[now].size()==) return ;
for(int i=;i<ve[now].size();i++){
if(!vis[ve[now][i]]){
tmp.pb(dfs(ve[now][i])+);
}
}
sort(tmp.begin(),tmp.end());
while(tmp.size()>){
if(tmp[tmp.size()-]+tmp[tmp.size()-]<=k) break;
ans++;
tmp.pop_back();
}
return tmp[tmp.size()-];
} int main(){
std::ios::sync_with_stdio(false);
cin>>n>>k;
int x,y;
for(int i=;i<n;i++){
cin>>x>>y;
ve[x].pb(y);
ve[y].pb(x);
}
for(int i=;i<=n;i++){
if(ve[i].size()>){
dfs(i);
break;
}
}
cout<<ans<<endl;
}

Codeforces Round #510 (Div. 2)的更多相关文章

  1. Codeforces Round #510 (Div. 2) D. Petya and Array(离散化+反向树状数组)

    http://codeforces.com/contest/1042/problem/D 题意 给一个数组n个元素,求有多少个连续的子序列的和<t (1<=n<=200000,abs ...

  2. Codeforces Round #510 (Div. 2) B. Vitamins

    B. Vitamins 题目链接:https://codeforces.com/contest/1042/problem/B 题意: 给出几种药,没种可能包含一种或多种(最多三种)维生素,现在问要吃到 ...

  3. Codeforces Round #510 (Div. 2) D. Petya and Array(树状数组)

    D. Petya and Array 题目链接:https://codeforces.com/contest/1042/problem/D 题意: 给出n个数,问一共有多少个区间,满足区间和小于t. ...

  4. Codeforces Round #510 (Div. 2)(C)

    传送门:Problem C https://www.cnblogs.com/violet-acmer/p/9682082.html 题意: 给你n个数,定义有两种操作 ① 1 i j : (i != ...

  5. Codeforces Round #510 (Div. 2)(B)

    传送门:Problem B https://www.cnblogs.com/violet-acmer/p/9682082.html 题意: 如果可以通过喝果汁将维生素A,B,C全部摄取,求最小花费,如 ...

  6. Codeforces Round #510 (Div. 2)(A)

    传送门:Problem A https://www.cnblogs.com/violet-acmer/p/9682082.html 题意: 公园里有n个沙滩,a[i]表示第i个沙滩初始人数,现有m个人 ...

  7. codeforces 1042d//Petya and Array// Codeforces Round #510 (Div. 2)

    题意:给出一个数组,求其中和小于t的区间数. 先计算前缀和数组sum[i].对当前的sum[i],查询树状数组中有几个比(sum[i]-t)大的数,那么用sum[i]减它就是一个合法区间.再将当前的s ...

  8. codeforces 1042c// Array Product// Codeforces Round #510(Div. 2)

    题意:给出一个数组,2种操作:.1:x*y然后x消失,2:除掉x(2操作最多只能进行一次).问最大的结果的一种操作方式.逻辑题,看能不能想全面. 1先数好0,正,负的数量,zero,pos,neg.如 ...

  9. Codeforces Round #510 Div. 2 Virtual Participate记

    这场打的顺手到不敢相信.如果不是vp的话估计肯定打不到这个成绩. A:最大显然,最小的话每次暴力给最小的+1. #include<iostream> #include<cstdio& ...

随机推荐

  1. Linq分组查询统计

    这里介绍Linq使用Group By和Count得到每个CategoryID中产品的数量,Linq使用Group By和Count得到每个CategoryID中断货产品的数量等方面. 学经常会遇到Li ...

  2. java web(七): mybatis的动态sql和mybatis generator自动生成pojo类和映射文件

    前言: MyBatis 的强大特性之一便是它的动态 SQL.如果你有使用 JDBC 或其它类似框架的经验,你就能体会到根据 不同条件拼接 SQL 语句的痛苦.例如拼接时要确保不能忘记添加必要的空格,还 ...

  3. 移动Web端资源整合

    meta篇 viewreport 视窗宽度 <meta name="viewport" content="width=device-width,initial-sc ...

  4. PythonStudy——字符编码 Character Encoding

    测试一下学习字符编码的问题:解决乱码问题 数据 从 硬盘 => 内存 => cpu应用程序打开文本文件的三步骤1.打开应用程序2.将数据加载到内存中3.cpu将内存中的数据直接翻译成字符显 ...

  5. linux下insmod模块出现“Invalid parameters"

    在编译一个模块时,会出现WARNING:"函数名" undefined!,这 说明该模块所依赖的模块还没有加载进内核,需要先加载所依赖的模块. 当加载依赖模块后,使用insmod会 ...

  6. MySQL Execution Plan--IN查询计划

    对于IN查询,MySQL会根据当前表数据结构(索引)和数据分布(统计信息和预估)生成多种执行计划,并根据执行成本挑选出“最优执行计划”. 假设有查询 SELECT * FROM student ,,, ...

  7. 程序猿大牛 Jeff Atwood 的两本中文书

    版权声明:本文为博主原创文章,未经博主同意不得转载. https://blog.csdn.net/happydeer/article/details/17094271 watermark/2/text ...

  8. Linux之cd、pwd、mkdir、rmdir

    cd.pwd.mkdir.rmdir 命令功能: 切换到指定的目录,可用绝对路径和相对路径 命令格式: cd directory 命令参数: 无 命令实例: 1.切换到/bin目录 vbird@Ubu ...

  9. dapper List SqlBulkCopy

    using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.D ...

  10. 无法获得锁 /var/lib/dpkg/lock - open (11: 资源暂时不可用) ...ubuntu 18.04 安装vim遇到的错误

    安装vim: sudo apt-get install vim-gtk 问题: E:无法获得锁 /var/lib/dpkg/lock - open (11: 资源暂时不可用) E:无法锁定管理目录(/ ...