Codeforces Round #441 Div. 1
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的更多相关文章
- Codeforces Round #441 (Div. 2)【A、B、C、D】
Codeforces Round #441 (Div. 2) codeforces 876 A. Trip For Meal(水题) 题意:R.O.E三点互连,给出任意两点间距离,你在R点,每次只能去 ...
- Codeforces Round #441 (Div. 2)
Codeforces Round #441 (Div. 2) A. Trip For Meal 题目描述:给出\(3\)个点,以及任意两个点之间的距离,求从\(1\)个点出发,再走\(n-1\)个点的 ...
- [日常] Codeforces Round #441 Div.2 实况
上次打了一发 Round #440 Div.2 结果被垃圾交互器卡掉 $200$ Rating后心情复杂... 然后立了个 Round #441 要翻上蓝的flag QAQ 晚饭回来就开始搞事情, 大 ...
- Codeforces Round #441 (Div. 2, by Moscow Team Olympiad) D. Sorting the Coins
http://codeforces.com/contest/876/problem/D 题意: 最开始有一串全部由"O"组成的字符串,现在给出n个数字,指的是每次把位置n上的&qu ...
- Codeforces Round #441 (Div. 2, by Moscow Team Olympiad) C. Classroom Watch
http://codeforces.com/contest/876/problem/C 题意: 现在有一个数n,它是由一个数x加上x每一位的数字得到的,现在给出n,要求找出符合条件的每一个x. 思路: ...
- 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. 思路: 差能 ...
- Codeforces Round #441 (Div. 2, by Moscow Team Olympiad) A. Trip For Meal
http://codeforces.com/contest/876/problem/A 题意: 一个人一天要吃n次蜂蜜,他有3个朋友,他第一次总是在一个固定的朋友家吃蜂蜜,如果说没有吃到n次,那么他就 ...
- 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, ...
- Codeforces Round #441(Div.2) F - High Cry
F - High Cry 题目大意:给你n个数,让你找区间里面所有数或 起来大于区间里面最大数的区间个数. 思路:反向思维,找出不符合的区间然后用总数减去.我们找出每个数掌控的最左端 和最右端,一个数 ...
随机推荐
- 你知道Java的四种引用类型吗
关于java四种引用类型,我也是刚了解,特此记下! 在Java中提供了四个级别的引用:强引用,软引用,弱引用和虚引用.在这四个引用类型中,只有强引用FinalReference类是包内可见,其他三种引 ...
- 下面哪项技术可以用在WEB开发中实现会话跟踪实现?
下面哪项技术可以用在WEB开发中实现会话跟踪实现? A:session B:Cookie C:地址重写 D:隐藏域 答案:ABCD 会话跟踪是一种灵活.轻便的机制,它使Web上的状态编程变为可能. H ...
- 【博客迁移】hyrepo.com
博客迁移至 www.hyrepo.com
- ASP.Net Core2.1中的HttpClientFactory系列二:集成Polly处理瞬态故障
前言:最近,同事在工作中遇到了使用HttpClient,有些请求超时的问题,辅导员让我下去调研一下,HttpClinet的使用方式已经改成了之前博客中提到的方式,问题的原因我已经找到了,就是因为使用了 ...
- python第八章:多任务--小白博客
多线程threading 多线程特点: #线程的并发是利用cpu上下文的切换(是并发,不是并行)#多线程执行的顺序是无序的#多线程共享全局变量#线程是继承在进程里的,没有进程就没有线程#GIL全局解释 ...
- Python学习第十五篇——类继承和类实例化
学习Python类时,我们明白了类的本质,以及所谓的面向对象编程思想强调的对事物本身的属性,我们对某一类事物进行描述——采用了很多方法,这些方法描述了类的属性(比如猫科动物的眼睛,四肢,是否哺乳类等等 ...
- NFV论文集(三)综述
一 文章名称:Dependability of the NFV Orchestrator: State of the Art and Research Challenges 发表时间:2018 期刊来 ...
- pycharm设置pytest运行程序
- html总结:文本框填满表格
<style> input { width: 100%; }</style>
- Docker 安装和配置
#centos 6 需要另外安装 yum install lxc libcgroup device-mapper-ecent-libs 推荐centos7 安装深事#centos 7 直接安装就好yu ...