A:显然答案与原数的差不会很大。

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<algorithm>
using namespace std;
#define ll long long
char getc(){char c=getchar();while ((c<'A'||c>'Z')&&(c<'a'||c>'z')&&(c<'0'||c>'9')) c=getchar();return c;}
int gcd(int n,int m){return m==0?n:gcd(m,n%m);}
int read()
{
int x=0,f=1;char c=getchar();
while (c<'0'||c>'9') {if (c=='-') f=-1;c=getchar();}
while (c>='0'&&c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar();
return x*f;
}
int n,ans[1000],u;
int calc(int n)
{
int s=0;
while (n) s+=n%10,n/=10;
return s;
}
signed main()
{
n=read();
for (int i=1;i<=min(n,1000);i++)
{
int x=n-i;
if (calc(x)==i) ans[++u]=x;
}
cout<<u<<endl;
for (int i=1;i<=u;i++) cout<<ans[i]<<endl;
return 0;
//NOTICE LONG LONG!!!!!
}

  B:即求不处于最右端的位置中有多少个1,随便维护。

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<algorithm>
using namespace std;
#define ll long long
#define N 300010
char getc(){char c=getchar();while ((c<'A'||c>'Z')&&(c<'a'||c>'z')&&(c<'0'||c>'9')) c=getchar();return c;}
int gcd(int n,int m){return m==0?n:gcd(m,n%m);}
int read()
{
int x=0,f=1;char c=getchar();
while (c<'0'||c>'9') {if (c=='-') f=-1;c=getchar();}
while (c>='0'&&c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar();
return x*f;
}
int n,a[N],ans;
bool flag[N];
signed main()
{
n=read();
for (int i=1;i<=n;i++) a[i]=read();
cout<<1<<' ';ans=1;int suf=n+1;
for (int i=1;i<=n;i++)
{
flag[a[i]]=1;
if (suf==a[i]+1)
{
suf=a[i];
while (flag[suf-1]) suf--;
}
ans++;cout<<ans-(n-suf+1)<<' ';
}
return 0;
//NOTICE LONG LONG!!!!!
}

  C:按位考虑,倒序贪心,必须改(即前缀与后一个串相同且该位较大)的时候才改。全部扫过一遍后可能仍不合法,需要按同样的做法重新扫一遍,并且可以证明扫两遍之后依旧不合法则无解。

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<vector>
using namespace std;
#define ll long long
#define N 100010
char getc(){char c=getchar();while ((c<'A'||c>'Z')&&(c<'a'||c>'z')&&(c<'0'||c>'9')) c=getchar();return c;}
int gcd(int n,int m){return m==0?n:gcd(m,n%m);}
int read()
{
int x=0,f=1;char c=getchar();
while (c<'0'||c>'9') {if (c=='-') f=-1;c=getchar();}
while (c>='0'&&c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar();
return x*f;
}
int n,m,len,p[N];
bool flag[N],same[N];
vector<int> a[N],pre[N];
bool astb(int i,int j,int x)
{
if (a[i].size()<=x) return 1;
if (a[j].size()<=x) return 0;
if (flag[a[j][x]]!=flag[a[i][x]]) return flag[a[i][x]];
else return a[i][x]<=a[j][x];
}
void error(){cout<<"No";exit(0);}
signed main()
{
#ifndef ONLINE_JUDGE
freopen("c.in","r",stdin);
freopen("c.out","w",stdout);
#endif
n=read(),m=read();
for (int i=1;i<=n;i++)
{
int m=read();len=max(len,m);
for (int j=0;j<m;j++) pre[i].push_back(p[j]),p[j]=i,a[i].push_back(read());
}
for (int t=3;t;t--)
{
for (int i=1;i<n;i++) same[i]=1;
for (int i=0;i<len;i++)
{
for (int k=p[i];k>=1;k=pre[k][i])
if (k<n)
{
if (same[k]&&!astb(k,k+1,i))
{
flag[a[k][i]]=1;
if (!astb(k,k+1,i)) error();
}
same[k]&=astb(k,k+1,i)&&astb(k+1,k,i);
}
}
}
for (int i=1;i<n;i++)
{
int f=-1;
for (int j=0;j<min(a[i].size(),a[i+1].size());j++)
{
if (a[i][j]!=a[i+1][j])
{
if (flag[a[i][j]]==flag[a[i+1][j]]) f=a[i][j]<a[i+1][j];
else f=flag[a[i][j]];
break;
}
}
if (f==0) error();
if (f==-1) if (a[i].size()>a[i+1].size()) error();
}
cout<<"Yes"<<endl;
int cnt=0;for (int i=1;i<=m;i++) if (flag[i]) cnt++;
cout<<cnt<<endl;
for (int i=1;i<=m;i++) if (flag[i]) cout<<i<<' ';
return 0;
//NOTICE LONG LONG!!!!!
}

  D:考虑枚举区间max,显然只要区间内存在一个数在max不为0的一位为1即可。随便预处理一下就完了。

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<algorithm>
using namespace std;
#define ll long long
#define N 200010
char getc(){char c=getchar();while ((c<'A'||c>'Z')&&(c<'a'||c>'z')&&(c<'0'||c>'9')) c=getchar();return c;}
int gcd(int n,int m){return m==0?n:gcd(m,n%m);}
int read()
{
int x=0,f=1;char c=getchar();
while (c<'0'||c>'9') {if (c=='-') f=-1;c=getchar();}
while (c>='0'&&c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar();
return x*f;
}
int n,a[N],pre[N][32],suf[N][32],PRE[N],SUF[N];
ll ans;
signed main()
{
#ifndef ONLINE_JUDGE
freopen("a.in","r",stdin);
freopen("a.out","w",stdout);
#endif
n=read();
for (int i=1;i<=n;i++) a[i]=read();
for (int i=1;i<=n;i++)
{
for (int j=0;j<32;j++) pre[i][j]=pre[i-1][j];
for (int j=0;j<32;j++)
if (a[i-1]&(1<<j)) pre[i][j]=i-1;
}
for (int j=0;j<32;j++) suf[n+1][j]=n+1;
for (int i=n;i>=1;i--)
{
for (int j=0;j<32;j++) suf[i][j]=suf[i+1][j];
for (int j=0;j<32;j++)
if (a[i+1]&(1<<j)) suf[i][j]=i+1;
}
a[0]=a[n+1]=1000000010;
for (int i=1;i<=n;i++)
{
int j=i-1;
while (a[j]<a[i]) j=PRE[j];
PRE[i]=j;
}
SUF[n+1]=n+1;
for (int i=n;i>=1;i--)
{
int j=i+1;
while (a[j]<=a[i]) j=SUF[j];
SUF[i]=j;
} for (int i=1;i<=n;i++)
{
int x=PRE[i],y=SUF[i];int u=PRE[i],v=SUF[i];
for (int j=0;j<32;j++)
if (!(a[i]&(1<<j))) u=max(u,pre[i][j]),v=min(v,suf[i][j]);
ans+=1ll*(SUF[i]-i)*(u-PRE[i])+1ll*(i-u)*(SUF[i]-v);
}
cout<<ans;
return 0;
//NOTICE LONG LONG!!!!!
}

  E:显然二分答案。考虑设f[i][0/1]表示第i个由A/B送是否合法,因为此时另一个人的位置并不重要。转移考虑另一个人上次送货是在哪,但这个转移无法实现,因为转移区间并不连续。但容易发现如果顺推过去就是连续的了。st表预处理区间minmax,二分得到转移边界,bit优化转移即可。

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<algorithm>
using namespace std;
#define ll long long
#define N 100010
#define inf 1000000000
char getc(){char c=getchar();while ((c<'A'||c>'Z')&&(c<'a'||c>'z')&&(c<'0'||c>'9')) c=getchar();return c;}
int gcd(int n,int m){return m==0?n:gcd(m,n%m);}
int read()
{
int x=0,f=1;char c=getchar();
while (c<'0'||c>'9') {if (c=='-') f=-1;c=getchar();}
while (c>='0'&&c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar();
return x*f;
}
int n,p,q,a[N][2],f[N][2],mn[N][18],mx[N][18],LG2[N],tree[N][2];
int query_max(int l,int r)
{
if (l>r) return 0;
return max(mx[l][LG2[r-l+1]],mx[r-(1<<LG2[r-l+1])+1][LG2[r-l+1]]);
}
int query_min(int l,int r)
{
if (l>r) return inf;
return min(mn[l][LG2[r-l+1]],mn[r-(1<<LG2[r-l+1])+1][LG2[r-l+1]]);
}
void add(int i,int k,int x){while (k<=n+1) tree[k][i]+=x,k+=k&-k;}
int query(int i,int k){int s=0;while (k) s+=tree[k][i],k-=k&-k;return s;}
bool check(int k)
{
memset(f,0,sizeof(f));
memset(tree,0,sizeof(tree));
//cout<<k<<endl;
f[0][0]=f[0][1]=1;
for (int i=0;i<=n;i++)
for (int j=0;j<2;j++)
{
if (i) f[i][j]=(query(j,i)>0);
if (f[i][j])
{
int l=i+1,r=n,x=i;
while (l<=r)
{
int mid=l+r>>1;
if (query_max(i+1,mid)-a[i][j]<=k&&a[i][j]-query_min(i+1,mid)<=k) x=mid,l=mid+1;
else r=mid-1;
}
//cout<<i<<' '<<j<<' '<<x<<' '<<a[i][j]<<' '<<query_max(i+1,x)<<' '<<query_min(i+1,x)<<endl;
add(j^1,i+1,1),add(j^1,x+1,-1);
}
}
return f[n][0]|f[n][1];
}
signed main()
{
#ifndef ONLINE_JUDGE
freopen("a.in","r",stdin);
freopen("a.out","w",stdout);
#endif
n=read(),a[0][0]=read(),a[0][1]=read();
for (int i=1;i<=n;i++) mn[i][0]=mx[i][0]=a[i][0]=a[i][1]=read();
for (int j=1;j<18;j++)
for (int i=1;i<=n;i++)
mx[i][j]=max(mx[i][j-1],mx[min(n,i+(1<<j-1))][j-1]),
mn[i][j]=min(mn[i][j-1],mn[min(n,i+(1<<j-1))][j-1]);
for (int i=2;i<=n;i++)
{
LG2[i]=LG2[i-1];
if ((2<<LG2[i])<=i) LG2[i]++;
}
int l=abs(a[0][0]-a[0][1]),r=inf,ans;
while (l<=r)
{
int mid=l+r>>1;
if (check(mid)) ans=mid,r=mid-1;
else l=mid+1;
}
cout<<ans;
return 0;
//NOTICE LONG LONG!!!!!
}

  F:按价值从大到小排序,逐个考虑,显然如果选择某个公主后仍然存在匹配方案,就应该将其选中,因为这至多会使后面的一位公主无法匹配,不选一定不优。

  然后考虑动态判断合法性。显然这是一个二分图匹配问题,但当然不能直接跑。注意到我们需要知道的只是二分图一侧是否存在完美匹配,考虑Hall定理,考虑该侧每个点集在另一侧与几个点相连。由于该侧的点只会与另一侧两个点相连,如果向一个连通块中新加入一个点,不会使得该连通块的任何与其在另一侧有公共点的点集更容易满足定理。所以只要整个连通块是满足Hall定理的,该侧所有点集也一定满足。于是只要用并查集维护二分图每个连通块两侧点的数量差即可。

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<algorithm>
using namespace std;
#define ll long long
#define N 200010
char getc(){char c=getchar();while ((c<'A'||c>'Z')&&(c<'a'||c>'z')&&(c<'0'||c>'9')) c=getchar();return c;}
int gcd(int n,int m){return m==0?n:gcd(m,n%m);}
int read()
{
int x=0,f=1;char c=getchar();
while (c<'0'||c>'9') {if (c=='-') f=-1;c=getchar();}
while (c>='0'&&c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar();
return x*f;
}
int n,m,ans,fa[N],size[N];
struct data
{
int x,y,z;
bool operator <(const data&a) const
{
return z>a.z;
}
}a[N];
int find(int x){return fa[x]==x?x:fa[x]=find(fa[x]);}
signed main()
{
#ifndef ONLINE_JUDGE
freopen("a.in","r",stdin);
freopen("a.out","w",stdout);
#endif
m=read(),n=read();
for (int i=1;i<=n;i++) a[i].x=read(),a[i].y=read(),a[i].z=read();
sort(a+1,a+n+1);
for (int i=1;i<=m;i++) fa[i]=i,size[i]=1;
for (int i=1;i<=n;i++)
{
int p=find(a[i].x),q=find(a[i].y);
if (p==q)
{
if (size[p]>=1) size[p]--,ans+=a[i].z;
}
else
{
if (size[p]|size[q]) size[p]+=size[q]-1,fa[q]=p,ans+=a[i].z;
}
}
cout<<ans;
return 0;
//NOTICE LONG LONG!!!!!
}

  

Codeforces Round #441 Div. 1的更多相关文章

  1. Codeforces Round #441 (Div. 2)【A、B、C、D】

    Codeforces Round #441 (Div. 2) codeforces 876 A. Trip For Meal(水题) 题意:R.O.E三点互连,给出任意两点间距离,你在R点,每次只能去 ...

  2. Codeforces Round #441 (Div. 2)

    Codeforces Round #441 (Div. 2) A. Trip For Meal 题目描述:给出\(3\)个点,以及任意两个点之间的距离,求从\(1\)个点出发,再走\(n-1\)个点的 ...

  3. [日常] Codeforces Round #441 Div.2 实况

    上次打了一发 Round #440 Div.2 结果被垃圾交互器卡掉 $200$ Rating后心情复杂... 然后立了个 Round #441 要翻上蓝的flag QAQ 晚饭回来就开始搞事情, 大 ...

  4. Codeforces Round #441 (Div. 2, by Moscow Team Olympiad) D. Sorting the Coins

    http://codeforces.com/contest/876/problem/D 题意: 最开始有一串全部由"O"组成的字符串,现在给出n个数字,指的是每次把位置n上的&qu ...

  5. Codeforces Round #441 (Div. 2, by Moscow Team Olympiad) C. Classroom Watch

    http://codeforces.com/contest/876/problem/C 题意: 现在有一个数n,它是由一个数x加上x每一位的数字得到的,现在给出n,要求找出符合条件的每一个x. 思路: ...

  6. Codeforces Round #441 (Div. 2, by Moscow Team Olympiad) B. Divisiblity of Differences

    http://codeforces.com/contest/876/problem/B 题意: 给出n个数,要求从里面选出k个数使得这k个数中任意两个的差能够被m整除,若不能则输出no. 思路: 差能 ...

  7. Codeforces Round #441 (Div. 2, by Moscow Team Olympiad) A. Trip For Meal

    http://codeforces.com/contest/876/problem/A 题意: 一个人一天要吃n次蜂蜜,他有3个朋友,他第一次总是在一个固定的朋友家吃蜂蜜,如果说没有吃到n次,那么他就 ...

  8. Codeforces Round #441 (Div. 2, by Moscow Team Olympiad)

    A. Trip For Meal 题目链接:http://codeforces.com/contest/876/problem/A 题目意思:现在三个点1,2,3,1-2的路程是a,1-3的路程是b, ...

  9. Codeforces Round #441(Div.2) F - High Cry

    F - High Cry 题目大意:给你n个数,让你找区间里面所有数或 起来大于区间里面最大数的区间个数. 思路:反向思维,找出不符合的区间然后用总数减去.我们找出每个数掌控的最左端 和最右端,一个数 ...

随机推荐

  1. jquery tooltip

    这是个加了点淡入淡出效果的顶部tooltip控件,会自动消失 用法: <head> <title></title> <link href="base ...

  2. NPOI生成excel并下载

    NPOI文件下载地址:http://npoi.codeplex.com/ 将文件直接引用至项目中即可,,,,, 虽然网上资料很多,但有可能并找不到自己想要的功能,今天闲的没事,所以就稍微整理了一个简单 ...

  3. .net core实践系列之短信服务-架构优化

    前言 通过前面的几篇文章,讲解了一个短信服务的架构设计与实现.然而初始方案并非100%完美的,我们仍可以对该架构做一些优化与调整. 同时我也希望通过这篇文章与大家分享一下,我的架构设计理念. 源码地址 ...

  4. 一次掌握 React 与 React Native 两个框架

    此系列文章将整合我的 React 视频教程与 React Native 书籍中的精华部分,给大家介绍 React 与 React Native 结合学习的方法. 1. 软件开发语言与框架的学习本质 我 ...

  5. hadoop和java 配置环境变量的的tar

    第一步:打开工具上传tar包 如下图 第二步:在文件路径下查看是否上传成功 第三步:解压tar包               tar -zxvf hadoop.2.6.5.tar.gz 第四步:配置环 ...

  6. python内涵段子爬取练习

    # -*- coding:utf-8 -*-from urllib import request as urllib2import re# 利用正则表达式爬取内涵段子url = r'http://ww ...

  7. SQL Server 2014备份维护计划

    1.      数据库 -> [管理]-> [维护计划]  -> [新建维护计划](如果没有操作过可以,选择“维护计划向导”): 2.      直接点击下一步,然后填写计划名称.说 ...

  8. MyBaits全局配置文件的各项标签1

    ■dtd约束     <!DOCTYPE configuration           PUBLIC "-//mybatis.org//DTD Config 3.0//EN" ...

  9. liunx 运维知识二部分

    Windows下的目录和Linux系统下的目录有什么区别? Windows目录下的文件一般都是分区(C盘,D盘...),C盘下面有什么目录,目录下面还有其他目录加上文件. Linux系统目录结构一切都 ...

  10. idea中 maven打包时时报错User setting file does not exist C:\Users\lenevo\.m2\setting.xml,

    第一种错误 :idea中 maven打包时时报错User setting file does not exist C:\Users\lenevo\.m2\setting.xml, 解决方案如下:将ma ...